Source Code
Latest 25 from a total of 1,802 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Create Sound And... | 112803277 | 834 days ago | IN | 0 ETH | 0.001215101196 | ||||
| Create Sound And... | 112802461 | 834 days ago | IN | 0 ETH | 0.001323262479 | ||||
| Create Sound And... | 112800186 | 834 days ago | IN | 0 ETH | 0.001280265123 | ||||
| Create Sound And... | 110677007 | 883 days ago | IN | 0 ETH | 0.00009576301 | ||||
| Create Sound And... | 110665176 | 884 days ago | IN | 0 ETH | 0.000147614589 | ||||
| Create Sound And... | 110660602 | 884 days ago | IN | 0 ETH | 0.000052869463 | ||||
| Create Sound And... | 110651516 | 884 days ago | IN | 0 ETH | 0.00007355054 | ||||
| Create Sound And... | 110641028 | 884 days ago | IN | 0 ETH | 0.00007083295 | ||||
| Create Sound And... | 110640451 | 884 days ago | IN | 0 ETH | 0.000080235189 | ||||
| Create Sound And... | 110638123 | 884 days ago | IN | 0 ETH | 0.000136810847 | ||||
| Create Sound And... | 110636649 | 884 days ago | IN | 0 ETH | 0.00014249733 | ||||
| Create Sound And... | 110624841 | 885 days ago | IN | 0 ETH | 0.000070788808 | ||||
| Create Sound And... | 110622289 | 885 days ago | IN | 0 ETH | 0.000068712476 | ||||
| Create Sound And... | 110620106 | 885 days ago | IN | 0 ETH | 0.000121939024 | ||||
| Create Sound And... | 110613777 | 885 days ago | IN | 0 ETH | 0.000077460659 | ||||
| Create Sound And... | 110605393 | 885 days ago | IN | 0 ETH | 0.000071786814 | ||||
| Create Sound And... | 110592345 | 885 days ago | IN | 0 ETH | 0.000075971037 | ||||
| Create Sound And... | 110584653 | 886 days ago | IN | 0 ETH | 0.000083350924 | ||||
| Create Sound And... | 110581749 | 886 days ago | IN | 0 ETH | 0.000080797856 | ||||
| Create Sound And... | 110554031 | 886 days ago | IN | 0 ETH | 0.000058786836 | ||||
| Create Sound And... | 110552666 | 886 days ago | IN | 0 ETH | 0.00005367667 | ||||
| Create Sound And... | 110550422 | 886 days ago | IN | 0 ETH | 0.000067966871 | ||||
| Create Sound And... | 110548699 | 886 days ago | IN | 0 ETH | 0.000053280642 | ||||
| Create Sound And... | 110545999 | 886 days ago | IN | 0 ETH | 0.000087497663 | ||||
| Create Sound And... | 110545774 | 886 days ago | IN | 0 ETH | 0.000155196269 |
Latest 25 internal transactions (View All)
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
SoundCreatorV1
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
/*
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒███████████████████████████████████████████████████████████
▒███████████████████████████████████████████████████████████
▒▓▓▓▓▓▓▓▓▓▓▓▓▓████████████████▓▓▓▓▓▓▓▓▓▓▓▓▓▓██████████████████████████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒
█████████████████████████████▓ ████████████████████████████████████████████
█████████████████████████████▓ ████████████████████████████████████████████
█████████████████████████████▓ ▒▒▒▒▒▒▒▒▒▒▒▒▒██████████████████████████████
█████████████████████████████▓ ▒█████████████████████████████
█████████████████████████████▓ ▒████████████████████████████
█████████████████████████████████████████████████████████▓
███████████████████████████████████████████████████████████
███████████████████████████████████████████████████████████▒
███████████████████████████████████████████████████████████▒
▓██████████████████████████████████████████████████████████▒
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓███████████████████████████████▒
█████████████████████████████ ▒█████████████████████████████▒
██████████████████████████████ ▒█████████████████████████████▒
██████████████████████████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒█████████████████████████████▒
████████████████████████████████████████████▒ ▒█████████████████████████████▒
████████████████████████████████████████████▒ ▒█████████████████████████████▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒███████████████████████████████▓▓▓▓▓▓▓▓▓▓▓▓▓███████████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▓█████████████████████████████████████████████████████████▒
▓██████████████████████████████████████████████████████████
*/
import { Clones } from "openzeppelin/proxy/Clones.sol";
import { ISoundCreatorV1 } from "./interfaces/ISoundCreatorV1.sol";
import { ISoundEditionV1_2 } from "./interfaces/ISoundEditionV1_2.sol";
import { IMetadataModule } from "./interfaces/IMetadataModule.sol";
import { OwnableRoles } from "solady/auth/OwnableRoles.sol";
/**
* @title SoundCreatorV1
* @notice A factory that deploys minimal proxies of `SoundEditionV1_2.sol`.
* @dev The proxies are OpenZeppelin's Clones implementation of https://eips.ethereum.org/EIPS/eip-1167
*/
contract SoundCreatorV1 is ISoundCreatorV1, OwnableRoles {
// =============================================================
// STORAGE
// =============================================================
/**
* @dev The implementation contract delegated to by Sound edition proxies.
*/
address public soundEditionImplementation;
// =============================================================
// CONSTRUCTOR
// =============================================================
constructor(address _soundEditionImplementation) implementationNotZero(_soundEditionImplementation) {
soundEditionImplementation = _soundEditionImplementation;
_initializeOwner(msg.sender);
}
// =============================================================
// PUBLIC / EXTERNAL WRITE FUNCTIONS
// =============================================================
/**
* @inheritdoc ISoundCreatorV1
*/
function createSoundAndMints(
bytes32 salt,
bytes calldata initData,
address[] calldata contracts,
bytes[] calldata data
) external returns (address soundEdition, bytes[] memory results) {
// Create Sound Edition proxy.
soundEdition = payable(Clones.cloneDeterministic(soundEditionImplementation, _saltedSalt(msg.sender, salt)));
// Initialize proxy.
assembly {
// Grab the free memory pointer.
let m := mload(0x40)
// Copy the `initData` to the free memory.
calldatacopy(m, initData.offset, initData.length)
// Call the initializer, and revert if the call fails.
if iszero(
call(
gas(), // Gas remaining.
soundEdition, // Address of the edition.
0, // `msg.value` of the call: 0 ETH.
m, // Start of input.
initData.length, // Length of input.
0x00, // Start of output. Not used.
0x00 // Size of output. Not used.
)
) {
// Bubble up the revert if the call reverts.
returndatacopy(0x00, 0x00, returndatasize())
revert(0x00, returndatasize())
}
}
results = _callContracts(contracts, data);
OwnableRoles(soundEdition).transferOwnership(msg.sender);
emit SoundEditionCreated(soundEdition, msg.sender, initData, contracts, data, results);
}
/**
* @inheritdoc ISoundCreatorV1
*/
function setEditionImplementation(address newImplementation)
external
onlyOwner
implementationNotZero(newImplementation)
{
soundEditionImplementation = newImplementation;
emit SoundEditionImplementationSet(soundEditionImplementation);
}
// =============================================================
// PUBLIC / EXTERNAL VIEW FUNCTIONS
// =============================================================
/**
* @inheritdoc ISoundCreatorV1
*/
function soundEditionAddress(address by, bytes32 salt) external view returns (address addr, bool exists) {
addr = Clones.predictDeterministicAddress(soundEditionImplementation, _saltedSalt(by, salt), address(this));
exists = addr.code.length > 0;
}
// =============================================================
// INTERNAL / PRIVATE HELPERS
// =============================================================
/**
* @dev Call the `contracts` in order with `data`.
* @param contracts The addresses of the contracts.
* @param data The `abi.encodeWithSelector` calldata for each of the contracts.
* @return results The results of calling the contracts.
*/
function _callContracts(address[] calldata contracts, bytes[] calldata data)
internal
returns (bytes[] memory results)
{
if (contracts.length != data.length) revert ArrayLengthsMismatch();
assembly {
// Grab the free memory pointer.
// We will use the free memory to construct the `results` array,
// and also as a temporary space for the calldata.
results := mload(0x40)
// Set `results.length` to be equal to `data.length`.
mstore(results, data.length)
// Skip the first word, which is used to store the length
let resultsOffsets := add(results, 0x20)
// Compute the location of the last calldata offset in `data`.
// `shl(5, n)` is a gas-saving shorthand for `mul(0x20, n)`.
let dataOffsetsEnd := add(data.offset, shl(5, data.length))
// This is the start of the unused free memory.
// We use it to temporarily store the calldata to call the contracts.
let m := add(resultsOffsets, shl(5, data.length))
// Loop through `contacts` and `data` together.
// prettier-ignore
for { let i := data.offset } iszero(eq(i, dataOffsetsEnd)) { i := add(i, 0x20) } {
// Location of `bytes[i]` in calldata.
let o := add(data.offset, calldataload(i))
// Copy `bytes[i]` from calldata to the free memory.
calldatacopy(
m, // Start of the unused free memory.
add(o, 0x20), // Location of starting byte of `data[i]` in calldata.
calldataload(o) // The length of the `bytes[i]`.
)
// Grab `contracts[i]` from the calldata.
// As `contracts` is the same length as `data`,
// `sub(i, data.offset)` gives the relative offset to apply to
// `contracts.offset` for `contracts[i]` to match `data[i]`.
let c := calldataload(add(contracts.offset, sub(i, data.offset)))
// Call the contract, and revert if the call fails.
if iszero(
call(
gas(), // Gas remaining.
c, // `contracts[i]`.
0, // `msg.value` of the call: 0 ETH.
m, // Start of the copy of `bytes[i]` in memory.
calldataload(o), // The length of the `bytes[i]`.
0x00, // Start of output. Not used.
0x00 // Size of output. Not used.
)
) {
// Bubble up the revert if the call reverts.
returndatacopy(0x00, 0x00, returndatasize())
revert(0x00, returndatasize())
}
// Append the current `m` into `resultsOffsets`.
mstore(resultsOffsets, m)
resultsOffsets := add(resultsOffsets, 0x20)
// Append the `returndatasize()` to `results`.
mstore(m, returndatasize())
// Append the return data to `results`.
returndatacopy(add(m, 0x20), 0x00, returndatasize())
// Advance `m` by `returndatasize() + 0x20`,
// rounded up to the next multiple of 32.
// `0x3f = 32 + 31`. The mask is `type(uint64).max & ~31`,
// which is big enough for all purposes (see memory expansion costs).
m := and(add(add(m, returndatasize()), 0x3f), 0xffffffffffffffe0)
}
// Allocate the memory for `results` by updating the free memory pointer.
mstore(0x40, m)
}
}
/**
* @dev Returns the salted salt.
* To prevent griefing and accidental collisions from clients that don't
* generate their salt properly.
* @param by The caller of the {createSoundAndMints} function.
* @param salt The salt, generated on the client side.
* @return result The computed value.
*/
function _saltedSalt(address by, bytes32 salt) internal pure returns (bytes32 result) {
assembly {
// Store the variables into the scratch space.
mstore(0x00, by)
mstore(0x20, salt)
// Equivalent to `keccak256(abi.encode(by, salt))`.
result := keccak256(0x00, 0x40)
}
}
/**
* @dev Reverts if the given implementation address is zero.
* @param implementation The address of the implementation.
*/
modifier implementationNotZero(address implementation) {
if (implementation == address(0)) {
revert ImplementationAddressCantBeZero();
}
_;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (proxy/Clones.sol)
pragma solidity ^0.8.0;
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*
* _Available since v3.4._
*/
library Clones {
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create(0, ptr, 0x37)
}
require(instance != address(0), "ERC1167: create failed");
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple time will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create2(0, ptr, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
mstore(add(ptr, 0x38), shl(0x60, deployer))
mstore(add(ptr, 0x4c), salt)
mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
predicted := keccak256(add(ptr, 0x37), 0x55)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(address implementation, bytes32 salt)
internal
view
returns (address predicted)
{
return predictDeterministicAddress(implementation, salt, address(this));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
import { IMetadataModule } from "./IMetadataModule.sol";
/**
* @title ISoundCreatorV1
* @notice The interface for the Sound edition factory.
*/
interface ISoundCreatorV1 {
// =============================================================
// EVENTS
// =============================================================
/**
* @dev Emitted when an edition is created.
* @param soundEdition The address of the edition.
* @param deployer The address of the deployer.
* @param initData The calldata to initialize SoundEdition via `abi.encodeWithSelector`.
* @param contracts The list of contracts called.
* @param data The list of calldata created via `abi.encodeWithSelector`
* @param results The results of calling the contracts. Use `abi.decode` to decode them.
*/
event SoundEditionCreated(
address indexed soundEdition,
address indexed deployer,
bytes initData,
address[] contracts,
bytes[] data,
bytes[] results
);
/**
* @dev Emitted when the edition implementation address is set.
* @param newImplementation The new implementation address to be set.
*/
event SoundEditionImplementationSet(address newImplementation);
// =============================================================
// ERRORS
// =============================================================
/**
* @dev Thrown if the implementation address is zero.
*/
error ImplementationAddressCantBeZero();
/**
* @dev Thrown if the lengths of the input arrays are not equal.
*/
error ArrayLengthsMismatch();
// =============================================================
// PUBLIC / EXTERNAL WRITE FUNCTIONS
// =============================================================
/**
* @dev Creates a Sound Edition proxy, initializes it,
* and creates mint configurations on a given set of minter addresses.
* @param salt The salt used for the CREATE2 to deploy the clone to a
* deterministic address.
* @param initData The calldata to initialize SoundEdition via
* `abi.encodeWithSelector`.
* @param contracts A list of contracts to call.
* @param data A list of calldata created via `abi.encodeWithSelector`
* This must contain the same number of entries as `contracts`.
* @return soundEdition Returns the address of the created contract.
* @return results The results of calling the contracts.
* Use `abi.decode` to decode them.
*/
function createSoundAndMints(
bytes32 salt,
bytes calldata initData,
address[] calldata contracts,
bytes[] calldata data
) external returns (address soundEdition, bytes[] memory results);
/**
* @dev Changes the SoundEdition implementation contract address.
*
* Calling conditions:
* - The caller must be the owner of the contract.
*
* @param newImplementation The new implementation address to be set.
*/
function setEditionImplementation(address newImplementation) external;
// =============================================================
// PUBLIC / EXTERNAL VIEW FUNCTIONS
// =============================================================
/**
* @dev The address of the sound edition implementation.
* @return The configured value.
*/
function soundEditionImplementation() external returns (address);
/**
* @dev Returns the deterministic address for the sound edition clone.
* @param by The caller of the {createSoundAndMints} function.
* @param salt The salt, generated on the client side.
* @return addr The computed address.
* @return exists Whether the contract exists.
*/
function soundEditionAddress(address by, bytes32 salt) external view returns (address addr, bool exists);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
import { IERC721AUpgradeable } from "chiru-labs/ERC721A-Upgradeable/IERC721AUpgradeable.sol";
import { IERC2981Upgradeable } from "openzeppelin-upgradeable/interfaces/IERC2981Upgradeable.sol";
import { IERC165Upgradeable } from "openzeppelin-upgradeable/utils/introspection/IERC165Upgradeable.sol";
import { IMetadataModule } from "./IMetadataModule.sol";
/**
* @dev The information pertaining to this edition.
*/
struct EditionInfo {
// Base URI for the tokenId.
string baseURI;
// Contract URI for OpenSea storefront.
string contractURI;
// Name of the collection.
string name;
// Symbol of the collection.
string symbol;
// Address that receives primary and secondary royalties.
address fundingRecipient;
// The current max mintable amount;
uint32 editionMaxMintable;
// The lower limit of the maximum number of tokens that can be minted.
uint32 editionMaxMintableUpper;
// The upper limit of the maximum number of tokens that can be minted.
uint32 editionMaxMintableLower;
// The timestamp (in seconds since unix epoch) after which the
// max amount of tokens mintable will drop from
// `maxMintableUpper` to `maxMintableLower`.
uint32 editionCutoffTime;
// Address of metadata module, address(0x00) if not used.
address metadataModule;
// The current mint randomness value.
uint256 mintRandomness;
// The royalty BPS (basis points).
uint16 royaltyBPS;
// Whether the mint randomness is enabled.
bool mintRandomnessEnabled;
// Whether the mint has concluded.
bool mintConcluded;
// Whether the metadata has been frozen.
bool isMetadataFrozen;
// Next token ID to be minted.
uint256 nextTokenId;
// Total number of tokens burned.
uint256 totalBurned;
// Total number of tokens minted.
uint256 totalMinted;
// Total number of tokens currently in existence.
uint256 totalSupply;
}
/**
* @title ISoundEditionV1_2
* @notice The interface for Sound edition contracts.
*/
interface ISoundEditionV1_2 is IERC721AUpgradeable, IERC2981Upgradeable {
// =============================================================
// EVENTS
// =============================================================
/**
* @dev Emitted when the metadata module is set.
* @param metadataModule the address of the metadata module.
*/
event MetadataModuleSet(address metadataModule);
/**
* @dev Emitted when the `baseURI` is set.
* @param baseURI the base URI of the edition.
*/
event BaseURISet(string baseURI);
/**
* @dev Emitted when the `contractURI` is set.
* @param contractURI The contract URI of the edition.
*/
event ContractURISet(string contractURI);
/**
* @dev Emitted when the metadata is frozen (e.g.: `baseURI` can no longer be changed).
* @param metadataModule The address of the metadata module.
* @param baseURI The base URI of the edition.
* @param contractURI The contract URI of the edition.
*/
event MetadataFrozen(address metadataModule, string baseURI, string contractURI);
/**
* @dev Emitted when the `fundingRecipient` is set.
* @param fundingRecipient The address of the funding recipient.
*/
event FundingRecipientSet(address fundingRecipient);
/**
* @dev Emitted when the `royaltyBPS` is set.
* @param bps The new royalty, measured in basis points.
*/
event RoyaltySet(uint16 bps);
/**
* @dev Emitted when the edition's maximum mintable token quantity range is set.
* @param editionMaxMintableLower_ The lower limit of the maximum number of tokens that can be minted.
* @param editionMaxMintableUpper_ The upper limit of the maximum number of tokens that can be minted.
*/
event EditionMaxMintableRangeSet(uint32 editionMaxMintableLower_, uint32 editionMaxMintableUpper_);
/**
* @dev Emitted when the edition's cutoff time set.
* @param editionCutoffTime_ The timestamp.
*/
event EditionCutoffTimeSet(uint32 editionCutoffTime_);
/**
* @dev Emitted when the `mintRandomnessEnabled` is set.
* @param mintRandomnessEnabled_ The boolean value.
*/
event MintRandomnessEnabledSet(bool mintRandomnessEnabled_);
/**
* @dev Emitted when the `operatorFilteringEnabled` is set.
* @param operatorFilteringEnabled_ The boolean value.
*/
event OperatorFilteringEnablededSet(bool operatorFilteringEnabled_);
/**
* @dev Emitted upon initialization.
* @param edition_ The address of the edition.
* @param name_ Name of the collection.
* @param symbol_ Symbol of the collection.
* @param metadataModule_ Address of metadata module, address(0x00) if not used.
* @param baseURI_ Base URI.
* @param contractURI_ Contract URI for OpenSea storefront.
* @param fundingRecipient_ Address that receives primary and secondary royalties.
* @param royaltyBPS_ Royalty amount in bps (basis points).
* @param editionMaxMintableLower_ The lower bound of the max mintable quantity for the edition.
* @param editionMaxMintableUpper_ The upper bound of the max mintable quantity for the edition.
* @param editionCutoffTime_ The timestamp after which `editionMaxMintable` drops from
* `editionMaxMintableUpper` to
* `max(_totalMinted(), editionMaxMintableLower)`.
* @param flags_ The bitwise OR result of the initialization flags.
* See: {METADATA_IS_FROZEN_FLAG}
* See: {MINT_RANDOMNESS_ENABLED_FLAG}
*/
event SoundEditionInitialized(
address indexed edition_,
string name_,
string symbol_,
address metadataModule_,
string baseURI_,
string contractURI_,
address fundingRecipient_,
uint16 royaltyBPS_,
uint32 editionMaxMintableLower_,
uint32 editionMaxMintableUpper_,
uint32 editionCutoffTime_,
uint8 flags_
);
/**
* @dev Emitted upon ETH withdrawal.
* @param recipient The recipient of the withdrawal.
* @param amount The amount withdrawn.
* @param caller The account that initiated the withdrawal.
*/
event ETHWithdrawn(address recipient, uint256 amount, address caller);
/**
* @dev Emitted upon ERC20 withdrawal.
* @param recipient The recipient of the withdrawal.
* @param tokens The addresses of the ERC20 tokens.
* @param amounts The amount of each token withdrawn.
* @param caller The account that initiated the withdrawal.
*/
event ERC20Withdrawn(address recipient, address[] tokens, uint256[] amounts, address caller);
/**
* @dev Emitted upon a mint.
* @param to The address to mint to.
* @param quantity The number of minted.
* @param fromTokenId The first token ID minted.
*/
event Minted(address to, uint256 quantity, uint256 fromTokenId);
/**
* @dev Emitted upon an airdrop.
* @param to The recipients of the airdrop.
* @param quantity The number of tokens airdropped to each address in `to`.
* @param fromTokenId The first token ID minted to the first address in `to`.
*/
event Airdropped(address[] to, uint256 quantity, uint256 fromTokenId);
/**
* @dev EIP-4906 event to signal marketplaces to refresh the metadata.
* @param fromTokenId The starting token ID.
* @param toTokenId The ending token ID.
*/
event BatchMetadataUpdate(uint256 fromTokenId, uint256 toTokenId);
/**
* @dev Emiited when the Sound Automated Market (i.e. bonding curve minter) is set.
* @param sam_ The Sound Automated Market.
*/
event SAMSet(address sam_);
// =============================================================
// ERRORS
// =============================================================
/**
* @dev The edition's metadata is frozen (e.g.: `baseURI` can no longer be changed).
*/
error MetadataIsFrozen();
/**
* @dev The given `royaltyBPS` is invalid.
*/
error InvalidRoyaltyBPS();
/**
* @dev The given `randomnessLockedAfterMinted` value is invalid.
*/
error InvalidRandomnessLock();
/**
* @dev The requested quantity exceeds the edition's remaining mintable token quantity.
* @param available The number of tokens remaining available for mint.
*/
error ExceedsEditionAvailableSupply(uint32 available);
/**
* @dev The given amount is invalid.
*/
error InvalidAmount();
/**
* @dev The given `fundingRecipient` address is invalid.
*/
error InvalidFundingRecipient();
/**
* @dev The `editionMaxMintableLower` must not be greater than `editionMaxMintableUpper`.
*/
error InvalidEditionMaxMintableRange();
/**
* @dev The `editionMaxMintable` has already been reached.
*/
error MaximumHasAlreadyBeenReached();
/**
* @dev The mint `quantity` cannot exceed `ADDRESS_BATCH_MINT_LIMIT` tokens.
*/
error ExceedsAddressBatchMintLimit();
/**
* @dev The mint randomness has already been revealed.
*/
error MintRandomnessAlreadyRevealed();
/**
* @dev No addresses to airdrop.
*/
error NoAddressesToAirdrop();
/**
* @dev The mint has already concluded.
*/
error MintHasConcluded();
/**
* @dev The mint has not concluded.
*/
error MintNotConcluded();
/**
* @dev Cannot perform the operation after a token has been minted.
*/
error MintsAlreadyExist();
/**
* @dev The token IDs must be in strictly ascending order.
*/
error TokenIdsNotStrictlyAscending();
/**
* @dev Please wait for a while before you burn.
*/
error CannotBurnImmediately();
// =============================================================
// PUBLIC / EXTERNAL WRITE FUNCTIONS
// =============================================================
/**
* @dev Initializes the contract.
* @param name_ Name of the collection.
* @param symbol_ Symbol of the collection.
* @param metadataModule_ Address of metadata module, address(0x00) if not used.
* @param baseURI_ Base URI.
* @param contractURI_ Contract URI for OpenSea storefront.
* @param fundingRecipient_ Address that receives primary and secondary royalties.
* @param royaltyBPS_ Royalty amount in bps (basis points).
* @param editionMaxMintableLower_ The lower bound of the max mintable quantity for the edition.
* @param editionMaxMintableUpper_ The upper bound of the max mintable quantity for the edition.
* @param editionCutoffTime_ The timestamp after which `editionMaxMintable` drops from
* `editionMaxMintableUpper` to
* `max(_totalMinted(), editionMaxMintableLower)`.
* @param flags_ The bitwise OR result of the initialization flags.
* See: {METADATA_IS_FROZEN_FLAG}
* See: {MINT_RANDOMNESS_ENABLED_FLAG}
*/
function initialize(
string memory name_,
string memory symbol_,
address metadataModule_,
string memory baseURI_,
string memory contractURI_,
address fundingRecipient_,
uint16 royaltyBPS_,
uint32 editionMaxMintableLower_,
uint32 editionMaxMintableUpper_,
uint32 editionCutoffTime_,
uint8 flags_
) external;
/**
* @dev Mints `quantity` tokens to addrress `to`
* Each token will be assigned a token ID that is consecutively increasing.
*
* Calling conditions:
* - The caller must be the owner of the contract, or have either the
* `ADMIN_ROLE`, `MINTER_ROLE`, which can be granted via {grantRole}.
* Multiple minters, such as different minter contracts,
* can be authorized simultaneously.
*
* @param to Address to mint to.
* @param quantity Number of tokens to mint.
* @return fromTokenId The first token ID minted.
*/
function mint(address to, uint256 quantity) external payable returns (uint256 fromTokenId);
/**
* @dev Mints `quantity` tokens to each of the addresses in `to`.
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the
* `ADMIN_ROLE`, which can be granted via {grantRole}.
*
* @param to Address to mint to.
* @param quantity Number of tokens to mint.
* @return fromTokenId The first token ID minted.
*/
function airdrop(address[] calldata to, uint256 quantity) external returns (uint256 fromTokenId);
/**
* @dev Mints `quantity` tokens to addrress `to`
* Each token will be assigned a token ID that is consecutively increasing.
*
* Calling conditions:
* - The caller must be the bonding curve contract.
*
* @param to Address to mint to.
* @param quantity Number of tokens to mint.
* @return fromTokenId The first token ID minted.
*/
function samMint(address to, uint256 quantity) external payable returns (uint256 fromTokenId);
/**
* @dev Burns the `tokenIds`.
*
* Calling conditions:
* - The caller must be the bonding curve contract.
*
* @param burner The initiator of the burn.
* @param tokenIds The list of token IDs to burn.
*/
function samBurn(address burner, uint256[] calldata tokenIds) external;
/**
* @dev Withdraws collected ETH royalties to the fundingRecipient.
*/
function withdrawETH() external;
/**
* @dev Withdraws collected ERC20 royalties to the fundingRecipient.
* @param tokens array of ERC20 tokens to withdraw
*/
function withdrawERC20(address[] calldata tokens) external;
/**
* @dev Sets metadata module.
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
*
* @param metadataModule Address of metadata module.
*/
function setMetadataModule(address metadataModule) external;
/**
* @dev Sets global base URI.
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
*
* @param baseURI The base URI to be set.
*/
function setBaseURI(string memory baseURI) external;
/**
* @dev Sets contract URI.
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
*
* @param contractURI The contract URI to be set.
*/
function setContractURI(string memory contractURI) external;
/**
* @dev Freezes metadata by preventing any more changes to base URI.
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
*/
function freezeMetadata() external;
/**
* @dev Sets funding recipient address.
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
*
* @param fundingRecipient Address to be set as the new funding recipient.
*/
function setFundingRecipient(address fundingRecipient) external;
/**
* @dev Sets royalty amount in bps (basis points).
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
*
* @param bps The new royalty basis points to be set.
*/
function setRoyalty(uint16 bps) external;
/**
* @dev Sets the edition max mintable range.
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
*
* @param editionMaxMintableLower_ The lower limit of the maximum number of tokens that can be minted.
* @param editionMaxMintableUpper_ The upper limit of the maximum number of tokens that can be minted.
*/
function setEditionMaxMintableRange(uint32 editionMaxMintableLower_, uint32 editionMaxMintableUpper_) external;
/**
* @dev Sets the timestamp after which, the `editionMaxMintable` drops
* from `editionMaxMintableUpper` to `editionMaxMintableLower.
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
*
* @param editionCutoffTime_ The timestamp.
*/
function setEditionCutoffTime(uint32 editionCutoffTime_) external;
/**
* @dev Sets whether the `mintRandomness` is enabled.
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
*
* @param mintRandomnessEnabled_ The boolean value.
*/
function setMintRandomnessEnabled(bool mintRandomnessEnabled_) external;
/**
* @dev Sets whether OpenSea operator filtering is enabled.
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
*
* @param operatorFilteringEnabled_ The boolean value.
*/
function setOperatorFilteringEnabled(bool operatorFilteringEnabled_) external;
/**
* @dev Emits an event to signal to marketplaces to refresh all the metadata.
*/
function emitAllMetadataUpdate() external;
/**
* @dev Sets the Sound Automated Market (i.e. bonding curve minter).
*
* Calling conditions:
* - The caller must be the owner of the contract, or have the `ADMIN_ROLE`.
*
* @param sam_ The Sound Automated Market.
*/
function setSAM(address sam_) external;
// =============================================================
// PUBLIC / EXTERNAL VIEW FUNCTIONS
// =============================================================
/**
* @dev Returns the edition info.
* @return editionInfo The latest value.
*/
function editionInfo() external view returns (EditionInfo memory editionInfo);
/**
* @dev Returns the minter role flag.
* @return The constant value.
*/
function MINTER_ROLE() external view returns (uint256);
/**
* @dev Returns the admin role flag.
* @return The constant value.
*/
function ADMIN_ROLE() external view returns (uint256);
/**
* @dev Returns the bit flag to freeze the metadata on initialization.
* @return The constant value.
*/
function METADATA_IS_FROZEN_FLAG() external pure returns (uint8);
/**
* @dev Returns the bit flag to enable the mint randomness feature on initialization.
* @return The constant value.
*/
function MINT_RANDOMNESS_ENABLED_FLAG() external pure returns (uint8);
/**
* @dev Returns the bit flag to enable OpenSea operator filtering.
* @return The constant value.
*/
function OPERATOR_FILTERING_ENABLED_FLAG() external pure returns (uint8);
/**
* @dev Returns the base token URI for the collection.
* @return The configured value.
*/
function baseURI() external view returns (string memory);
/**
* @dev Returns the contract URI to be used by Opensea.
* See: https://docs.opensea.io/docs/contract-level-metadata
* @return The configured value.
*/
function contractURI() external view returns (string memory);
/**
* @dev Returns the address of the funding recipient.
* @return The configured value.
*/
function fundingRecipient() external view returns (address);
/**
* @dev Returns the maximum amount of tokens mintable for this edition.
* @return The configured value.
*/
function editionMaxMintable() external view returns (uint32);
/**
* @dev Returns the upper bound for the maximum tokens that can be minted for this edition.
* @return The configured value.
*/
function editionMaxMintableUpper() external view returns (uint32);
/**
* @dev Returns the lower bound for the maximum tokens that can be minted for this edition.
* @return The configured value.
*/
function editionMaxMintableLower() external view returns (uint32);
/**
* @dev Returns the timestamp after which `editionMaxMintable` drops from
* `editionMaxMintableUpper` to `editionMaxMintableLower`.
* @return The configured value.
*/
function editionCutoffTime() external view returns (uint32);
/**
* @dev Returns the address of the metadata module.
* @return The configured value.
*/
function metadataModule() external view returns (address);
/**
* @dev Returns the randomness based on latest block hash, which is stored upon each mint.
* unless {mintConcluded} is true.
* Used for game mechanics like the Sound Golden Egg.
* Returns 0 before revealed.
* WARNING: This value should NOT be used for any reward of significant monetary
* value, due to it being computed via a purely on-chain psuedorandom mechanism.
* @return The latest value.
*/
function mintRandomness() external view returns (uint256);
/**
* @dev Returns whether the `mintRandomness` has been enabled.
* @return The configured value.
*/
function mintRandomnessEnabled() external view returns (bool);
/**
* @dev Returns whether the `operatorFilteringEnabled` has been enabled.
* @return The configured value.
*/
function operatorFilteringEnabled() external view returns (bool);
/**
* @dev Returns whether the mint has been concluded.
* @return The latest value.
*/
function mintConcluded() external view returns (bool);
/**
* @dev Returns the royalty basis points.
* @return The configured value.
*/
function royaltyBPS() external view returns (uint16);
/**
* @dev Returns whether the metadata module is frozen.
* @return The configured value.
*/
function isMetadataFrozen() external view returns (bool);
/**
* @dev Returns the sound automated market, if any.
* @return The configured value.
*/
function sam() external view returns (address);
/**
* @dev Returns the next token ID to be minted.
* @return The latest value.
*/
function nextTokenId() external view returns (uint256);
/**
* @dev Returns the number of tokens minted by `owner`.
* @param owner Address to query for number minted.
* @return The latest value.
*/
function numberMinted(address owner) external view returns (uint256);
/**
* @dev Returns the number of tokens burned by `owner`.
* @param owner Address to query for number burned.
* @return The latest value.
*/
function numberBurned(address owner) external view returns (uint256);
/**
* @dev Returns the total amount of tokens minted.
* @return The latest value.
*/
function totalMinted() external view returns (uint256);
/**
* @dev Returns the total amount of tokens burned.
* @return The latest value.
*/
function totalBurned() external view returns (uint256);
/**
* @dev Informs other contracts which interfaces this contract supports.
* Required by https://eips.ethereum.org/EIPS/eip-165
* @param interfaceId The interface id to check.
* @return Whether the `interfaceId` is supported.
*/
function supportsInterface(bytes4 interfaceId)
external
view
override(IERC721AUpgradeable, IERC165Upgradeable)
returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
/**
* @title IMetadataModule
* @notice The interface for custom metadata modules.
*/
interface IMetadataModule {
/**
* @dev When implemented, SoundEdition's `tokenURI` redirects execution to this `tokenURI`.
* @param tokenId The token ID to retrieve the token URI for.
* @return The token URI string.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "./Ownable.sol";
/// @notice Simple single owner and multiroles authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
/// @dev While the ownable portion follows [EIP-173](https://eips.ethereum.org/EIPS/eip-173)
/// for compatibility, the nomenclature for the 2-step ownership handover and roles
/// may be unique to this codebase.
abstract contract OwnableRoles is Ownable {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev `bytes4(keccak256(bytes("Unauthorized()")))`.
uint256 private constant _UNAUTHORIZED_ERROR_SELECTOR = 0x82b42900;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EVENTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The `user`'s roles is updated to `roles`.
/// Each bit of `roles` represents whether the role is set.
event RolesUpdated(address indexed user, uint256 indexed roles);
/// @dev `keccak256(bytes("RolesUpdated(address,uint256)"))`.
uint256 private constant _ROLES_UPDATED_EVENT_SIGNATURE =
0x715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STORAGE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The role slot of `user` is given by:
/// ```
/// mstore(0x00, or(shl(96, user), _ROLE_SLOT_SEED))
/// let roleSlot := keccak256(0x00, 0x20)
/// ```
/// This automatically ignores the upper bits of the `user` in case
/// they are not clean, as well as keep the `keccak256` under 32-bytes.
///
/// Note: This is equal to `_OWNER_SLOT_NOT` in for gas efficiency.
uint256 private constant _ROLE_SLOT_SEED = 0x8b78c6d8;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Grants the roles directly without authorization guard.
/// Each bit of `roles` represents the role to turn on.
function _grantRoles(address user, uint256 roles) internal virtual {
/// @solidity memory-safe-assembly
assembly {
// Compute the role slot.
mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, user)
let roleSlot := keccak256(0x0c, 0x20)
// Load the current value and `or` it with `roles`.
roles := or(sload(roleSlot), roles)
// Store the new value.
sstore(roleSlot, roles)
// Emit the {RolesUpdated} event.
log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), roles)
}
}
/// @dev Removes the roles directly without authorization guard.
/// Each bit of `roles` represents the role to turn off.
function _removeRoles(address user, uint256 roles) internal virtual {
/// @solidity memory-safe-assembly
assembly {
// Compute the role slot.
mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, user)
let roleSlot := keccak256(0x0c, 0x20)
// Load the current value.
let currentRoles := sload(roleSlot)
// Use `and` to compute the intersection of `currentRoles` and `roles`,
// `xor` it with `currentRoles` to flip the bits in the intersection.
roles := xor(currentRoles, and(currentRoles, roles))
// Then, store the new value.
sstore(roleSlot, roles)
// Emit the {RolesUpdated} event.
log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), roles)
}
}
/// @dev Throws if the sender does not have any of the `roles`.
function _checkRoles(uint256 roles) internal view virtual {
/// @solidity memory-safe-assembly
assembly {
// Compute the role slot.
mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, caller())
// Load the stored value, and if the `and` intersection
// of the value and `roles` is zero, revert.
if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {
mstore(0x00, _UNAUTHORIZED_ERROR_SELECTOR)
revert(0x1c, 0x04)
}
}
}
/// @dev Throws if the sender is not the owner,
/// and does not have any of the `roles`.
/// Checks for ownership first, then lazily checks for roles.
function _checkOwnerOrRoles(uint256 roles) internal view virtual {
/// @solidity memory-safe-assembly
assembly {
// If the caller is not the stored owner.
// Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`.
if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) {
// Compute the role slot.
mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, caller())
// Load the stored value, and if the `and` intersection
// of the value and `roles` is zero, revert.
if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {
mstore(0x00, _UNAUTHORIZED_ERROR_SELECTOR)
revert(0x1c, 0x04)
}
}
}
}
/// @dev Throws if the sender does not have any of the `roles`,
/// and is not the owner.
/// Checks for roles first, then lazily checks for ownership.
function _checkRolesOrOwner(uint256 roles) internal view virtual {
/// @solidity memory-safe-assembly
assembly {
// Compute the role slot.
mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, caller())
// Load the stored value, and if the `and` intersection
// of the value and `roles` is zero, revert.
if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {
// If the caller is not the stored owner.
// Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`.
if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) {
mstore(0x00, _UNAUTHORIZED_ERROR_SELECTOR)
revert(0x1c, 0x04)
}
}
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PUBLIC UPDATE FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Allows the owner to grant `user` `roles`.
/// If the `user` already has a role, then it will be an no-op for the role.
function grantRoles(address user, uint256 roles) public payable virtual onlyOwner {
_grantRoles(user, roles);
}
/// @dev Allows the owner to remove `user` `roles`.
/// If the `user` does not have a role, then it will be an no-op for the role.
function revokeRoles(address user, uint256 roles) public payable virtual onlyOwner {
_removeRoles(user, roles);
}
/// @dev Allow the caller to remove their own roles.
/// If the caller does not have a role, then it will be an no-op for the role.
function renounceRoles(uint256 roles) public payable virtual {
_removeRoles(msg.sender, roles);
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PUBLIC READ FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns whether `user` has any of `roles`.
function hasAnyRole(address user, uint256 roles) public view virtual returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
// Compute the role slot.
mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, user)
// Load the stored value, and set the result to whether the
// `and` intersection of the value and `roles` is not zero.
result := iszero(iszero(and(sload(keccak256(0x0c, 0x20)), roles)))
}
}
/// @dev Returns whether `user` has all of `roles`.
function hasAllRoles(address user, uint256 roles) public view virtual returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
// Compute the role slot.
mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, user)
// Whether the stored value is contains all the set bits in `roles`.
result := eq(and(sload(keccak256(0x0c, 0x20)), roles), roles)
}
}
/// @dev Returns the roles of `user`.
function rolesOf(address user) public view virtual returns (uint256 roles) {
/// @solidity memory-safe-assembly
assembly {
// Compute the role slot.
mstore(0x0c, _ROLE_SLOT_SEED)
mstore(0x00, user)
// Load the stored value.
roles := sload(keccak256(0x0c, 0x20))
}
}
/// @dev Convenience function to return a `roles` bitmap from an array of `ordinals`.
/// This is meant for frontends like Etherscan, and is therefore not fully optimized.
/// Not recommended to be called on-chain.
function rolesFromOrdinals(uint8[] memory ordinals) public pure returns (uint256 roles) {
/// @solidity memory-safe-assembly
assembly {
for { let i := shl(5, mload(ordinals)) } i { i := sub(i, 0x20) } {
// We don't need to mask the values of `ordinals`, as Solidity
// cleans dirty upper bits when storing variables into memory.
roles := or(shl(mload(add(ordinals, i)), 1), roles)
}
}
}
/// @dev Convenience function to return an array of `ordinals` from the `roles` bitmap.
/// This is meant for frontends like Etherscan, and is therefore not fully optimized.
/// Not recommended to be called on-chain.
function ordinalsFromRoles(uint256 roles) public pure returns (uint8[] memory ordinals) {
/// @solidity memory-safe-assembly
assembly {
// Grab the pointer to the free memory.
ordinals := mload(0x40)
let ptr := add(ordinals, 0x20)
let o := 0
// The absence of lookup tables, De Bruijn, etc., here is intentional for
// smaller bytecode, as this function is not meant to be called on-chain.
for { let t := roles } 1 {} {
mstore(ptr, o)
// `shr` 5 is equivalent to multiplying by 0x20.
// Push back into the ordinals array if the bit is set.
ptr := add(ptr, shl(5, and(t, 1)))
o := add(o, 1)
t := shr(o, roles)
if iszero(t) { break }
}
// Store the length of `ordinals`.
mstore(ordinals, shr(5, sub(ptr, add(ordinals, 0x20))))
// Allocate the memory.
mstore(0x40, ptr)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* MODIFIERS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Marks a function as only callable by an account with `roles`.
modifier onlyRoles(uint256 roles) virtual {
_checkRoles(roles);
_;
}
/// @dev Marks a function as only callable by the owner or by an account
/// with `roles`. Checks for ownership first, then lazily checks for roles.
modifier onlyOwnerOrRoles(uint256 roles) virtual {
_checkOwnerOrRoles(roles);
_;
}
/// @dev Marks a function as only callable by an account with `roles`
/// or the owner. Checks for roles first, then lazily checks for ownership.
modifier onlyRolesOrOwner(uint256 roles) virtual {
_checkRolesOrOwner(roles);
_;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ROLE CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
// IYKYK
uint256 internal constant _ROLE_0 = 1 << 0;
uint256 internal constant _ROLE_1 = 1 << 1;
uint256 internal constant _ROLE_2 = 1 << 2;
uint256 internal constant _ROLE_3 = 1 << 3;
uint256 internal constant _ROLE_4 = 1 << 4;
uint256 internal constant _ROLE_5 = 1 << 5;
uint256 internal constant _ROLE_6 = 1 << 6;
uint256 internal constant _ROLE_7 = 1 << 7;
uint256 internal constant _ROLE_8 = 1 << 8;
uint256 internal constant _ROLE_9 = 1 << 9;
uint256 internal constant _ROLE_10 = 1 << 10;
uint256 internal constant _ROLE_11 = 1 << 11;
uint256 internal constant _ROLE_12 = 1 << 12;
uint256 internal constant _ROLE_13 = 1 << 13;
uint256 internal constant _ROLE_14 = 1 << 14;
uint256 internal constant _ROLE_15 = 1 << 15;
uint256 internal constant _ROLE_16 = 1 << 16;
uint256 internal constant _ROLE_17 = 1 << 17;
uint256 internal constant _ROLE_18 = 1 << 18;
uint256 internal constant _ROLE_19 = 1 << 19;
uint256 internal constant _ROLE_20 = 1 << 20;
uint256 internal constant _ROLE_21 = 1 << 21;
uint256 internal constant _ROLE_22 = 1 << 22;
uint256 internal constant _ROLE_23 = 1 << 23;
uint256 internal constant _ROLE_24 = 1 << 24;
uint256 internal constant _ROLE_25 = 1 << 25;
uint256 internal constant _ROLE_26 = 1 << 26;
uint256 internal constant _ROLE_27 = 1 << 27;
uint256 internal constant _ROLE_28 = 1 << 28;
uint256 internal constant _ROLE_29 = 1 << 29;
uint256 internal constant _ROLE_30 = 1 << 30;
uint256 internal constant _ROLE_31 = 1 << 31;
uint256 internal constant _ROLE_32 = 1 << 32;
uint256 internal constant _ROLE_33 = 1 << 33;
uint256 internal constant _ROLE_34 = 1 << 34;
uint256 internal constant _ROLE_35 = 1 << 35;
uint256 internal constant _ROLE_36 = 1 << 36;
uint256 internal constant _ROLE_37 = 1 << 37;
uint256 internal constant _ROLE_38 = 1 << 38;
uint256 internal constant _ROLE_39 = 1 << 39;
uint256 internal constant _ROLE_40 = 1 << 40;
uint256 internal constant _ROLE_41 = 1 << 41;
uint256 internal constant _ROLE_42 = 1 << 42;
uint256 internal constant _ROLE_43 = 1 << 43;
uint256 internal constant _ROLE_44 = 1 << 44;
uint256 internal constant _ROLE_45 = 1 << 45;
uint256 internal constant _ROLE_46 = 1 << 46;
uint256 internal constant _ROLE_47 = 1 << 47;
uint256 internal constant _ROLE_48 = 1 << 48;
uint256 internal constant _ROLE_49 = 1 << 49;
uint256 internal constant _ROLE_50 = 1 << 50;
uint256 internal constant _ROLE_51 = 1 << 51;
uint256 internal constant _ROLE_52 = 1 << 52;
uint256 internal constant _ROLE_53 = 1 << 53;
uint256 internal constant _ROLE_54 = 1 << 54;
uint256 internal constant _ROLE_55 = 1 << 55;
uint256 internal constant _ROLE_56 = 1 << 56;
uint256 internal constant _ROLE_57 = 1 << 57;
uint256 internal constant _ROLE_58 = 1 << 58;
uint256 internal constant _ROLE_59 = 1 << 59;
uint256 internal constant _ROLE_60 = 1 << 60;
uint256 internal constant _ROLE_61 = 1 << 61;
uint256 internal constant _ROLE_62 = 1 << 62;
uint256 internal constant _ROLE_63 = 1 << 63;
uint256 internal constant _ROLE_64 = 1 << 64;
uint256 internal constant _ROLE_65 = 1 << 65;
uint256 internal constant _ROLE_66 = 1 << 66;
uint256 internal constant _ROLE_67 = 1 << 67;
uint256 internal constant _ROLE_68 = 1 << 68;
uint256 internal constant _ROLE_69 = 1 << 69;
uint256 internal constant _ROLE_70 = 1 << 70;
uint256 internal constant _ROLE_71 = 1 << 71;
uint256 internal constant _ROLE_72 = 1 << 72;
uint256 internal constant _ROLE_73 = 1 << 73;
uint256 internal constant _ROLE_74 = 1 << 74;
uint256 internal constant _ROLE_75 = 1 << 75;
uint256 internal constant _ROLE_76 = 1 << 76;
uint256 internal constant _ROLE_77 = 1 << 77;
uint256 internal constant _ROLE_78 = 1 << 78;
uint256 internal constant _ROLE_79 = 1 << 79;
uint256 internal constant _ROLE_80 = 1 << 80;
uint256 internal constant _ROLE_81 = 1 << 81;
uint256 internal constant _ROLE_82 = 1 << 82;
uint256 internal constant _ROLE_83 = 1 << 83;
uint256 internal constant _ROLE_84 = 1 << 84;
uint256 internal constant _ROLE_85 = 1 << 85;
uint256 internal constant _ROLE_86 = 1 << 86;
uint256 internal constant _ROLE_87 = 1 << 87;
uint256 internal constant _ROLE_88 = 1 << 88;
uint256 internal constant _ROLE_89 = 1 << 89;
uint256 internal constant _ROLE_90 = 1 << 90;
uint256 internal constant _ROLE_91 = 1 << 91;
uint256 internal constant _ROLE_92 = 1 << 92;
uint256 internal constant _ROLE_93 = 1 << 93;
uint256 internal constant _ROLE_94 = 1 << 94;
uint256 internal constant _ROLE_95 = 1 << 95;
uint256 internal constant _ROLE_96 = 1 << 96;
uint256 internal constant _ROLE_97 = 1 << 97;
uint256 internal constant _ROLE_98 = 1 << 98;
uint256 internal constant _ROLE_99 = 1 << 99;
uint256 internal constant _ROLE_100 = 1 << 100;
uint256 internal constant _ROLE_101 = 1 << 101;
uint256 internal constant _ROLE_102 = 1 << 102;
uint256 internal constant _ROLE_103 = 1 << 103;
uint256 internal constant _ROLE_104 = 1 << 104;
uint256 internal constant _ROLE_105 = 1 << 105;
uint256 internal constant _ROLE_106 = 1 << 106;
uint256 internal constant _ROLE_107 = 1 << 107;
uint256 internal constant _ROLE_108 = 1 << 108;
uint256 internal constant _ROLE_109 = 1 << 109;
uint256 internal constant _ROLE_110 = 1 << 110;
uint256 internal constant _ROLE_111 = 1 << 111;
uint256 internal constant _ROLE_112 = 1 << 112;
uint256 internal constant _ROLE_113 = 1 << 113;
uint256 internal constant _ROLE_114 = 1 << 114;
uint256 internal constant _ROLE_115 = 1 << 115;
uint256 internal constant _ROLE_116 = 1 << 116;
uint256 internal constant _ROLE_117 = 1 << 117;
uint256 internal constant _ROLE_118 = 1 << 118;
uint256 internal constant _ROLE_119 = 1 << 119;
uint256 internal constant _ROLE_120 = 1 << 120;
uint256 internal constant _ROLE_121 = 1 << 121;
uint256 internal constant _ROLE_122 = 1 << 122;
uint256 internal constant _ROLE_123 = 1 << 123;
uint256 internal constant _ROLE_124 = 1 << 124;
uint256 internal constant _ROLE_125 = 1 << 125;
uint256 internal constant _ROLE_126 = 1 << 126;
uint256 internal constant _ROLE_127 = 1 << 127;
uint256 internal constant _ROLE_128 = 1 << 128;
uint256 internal constant _ROLE_129 = 1 << 129;
uint256 internal constant _ROLE_130 = 1 << 130;
uint256 internal constant _ROLE_131 = 1 << 131;
uint256 internal constant _ROLE_132 = 1 << 132;
uint256 internal constant _ROLE_133 = 1 << 133;
uint256 internal constant _ROLE_134 = 1 << 134;
uint256 internal constant _ROLE_135 = 1 << 135;
uint256 internal constant _ROLE_136 = 1 << 136;
uint256 internal constant _ROLE_137 = 1 << 137;
uint256 internal constant _ROLE_138 = 1 << 138;
uint256 internal constant _ROLE_139 = 1 << 139;
uint256 internal constant _ROLE_140 = 1 << 140;
uint256 internal constant _ROLE_141 = 1 << 141;
uint256 internal constant _ROLE_142 = 1 << 142;
uint256 internal constant _ROLE_143 = 1 << 143;
uint256 internal constant _ROLE_144 = 1 << 144;
uint256 internal constant _ROLE_145 = 1 << 145;
uint256 internal constant _ROLE_146 = 1 << 146;
uint256 internal constant _ROLE_147 = 1 << 147;
uint256 internal constant _ROLE_148 = 1 << 148;
uint256 internal constant _ROLE_149 = 1 << 149;
uint256 internal constant _ROLE_150 = 1 << 150;
uint256 internal constant _ROLE_151 = 1 << 151;
uint256 internal constant _ROLE_152 = 1 << 152;
uint256 internal constant _ROLE_153 = 1 << 153;
uint256 internal constant _ROLE_154 = 1 << 154;
uint256 internal constant _ROLE_155 = 1 << 155;
uint256 internal constant _ROLE_156 = 1 << 156;
uint256 internal constant _ROLE_157 = 1 << 157;
uint256 internal constant _ROLE_158 = 1 << 158;
uint256 internal constant _ROLE_159 = 1 << 159;
uint256 internal constant _ROLE_160 = 1 << 160;
uint256 internal constant _ROLE_161 = 1 << 161;
uint256 internal constant _ROLE_162 = 1 << 162;
uint256 internal constant _ROLE_163 = 1 << 163;
uint256 internal constant _ROLE_164 = 1 << 164;
uint256 internal constant _ROLE_165 = 1 << 165;
uint256 internal constant _ROLE_166 = 1 << 166;
uint256 internal constant _ROLE_167 = 1 << 167;
uint256 internal constant _ROLE_168 = 1 << 168;
uint256 internal constant _ROLE_169 = 1 << 169;
uint256 internal constant _ROLE_170 = 1 << 170;
uint256 internal constant _ROLE_171 = 1 << 171;
uint256 internal constant _ROLE_172 = 1 << 172;
uint256 internal constant _ROLE_173 = 1 << 173;
uint256 internal constant _ROLE_174 = 1 << 174;
uint256 internal constant _ROLE_175 = 1 << 175;
uint256 internal constant _ROLE_176 = 1 << 176;
uint256 internal constant _ROLE_177 = 1 << 177;
uint256 internal constant _ROLE_178 = 1 << 178;
uint256 internal constant _ROLE_179 = 1 << 179;
uint256 internal constant _ROLE_180 = 1 << 180;
uint256 internal constant _ROLE_181 = 1 << 181;
uint256 internal constant _ROLE_182 = 1 << 182;
uint256 internal constant _ROLE_183 = 1 << 183;
uint256 internal constant _ROLE_184 = 1 << 184;
uint256 internal constant _ROLE_185 = 1 << 185;
uint256 internal constant _ROLE_186 = 1 << 186;
uint256 internal constant _ROLE_187 = 1 << 187;
uint256 internal constant _ROLE_188 = 1 << 188;
uint256 internal constant _ROLE_189 = 1 << 189;
uint256 internal constant _ROLE_190 = 1 << 190;
uint256 internal constant _ROLE_191 = 1 << 191;
uint256 internal constant _ROLE_192 = 1 << 192;
uint256 internal constant _ROLE_193 = 1 << 193;
uint256 internal constant _ROLE_194 = 1 << 194;
uint256 internal constant _ROLE_195 = 1 << 195;
uint256 internal constant _ROLE_196 = 1 << 196;
uint256 internal constant _ROLE_197 = 1 << 197;
uint256 internal constant _ROLE_198 = 1 << 198;
uint256 internal constant _ROLE_199 = 1 << 199;
uint256 internal constant _ROLE_200 = 1 << 200;
uint256 internal constant _ROLE_201 = 1 << 201;
uint256 internal constant _ROLE_202 = 1 << 202;
uint256 internal constant _ROLE_203 = 1 << 203;
uint256 internal constant _ROLE_204 = 1 << 204;
uint256 internal constant _ROLE_205 = 1 << 205;
uint256 internal constant _ROLE_206 = 1 << 206;
uint256 internal constant _ROLE_207 = 1 << 207;
uint256 internal constant _ROLE_208 = 1 << 208;
uint256 internal constant _ROLE_209 = 1 << 209;
uint256 internal constant _ROLE_210 = 1 << 210;
uint256 internal constant _ROLE_211 = 1 << 211;
uint256 internal constant _ROLE_212 = 1 << 212;
uint256 internal constant _ROLE_213 = 1 << 213;
uint256 internal constant _ROLE_214 = 1 << 214;
uint256 internal constant _ROLE_215 = 1 << 215;
uint256 internal constant _ROLE_216 = 1 << 216;
uint256 internal constant _ROLE_217 = 1 << 217;
uint256 internal constant _ROLE_218 = 1 << 218;
uint256 internal constant _ROLE_219 = 1 << 219;
uint256 internal constant _ROLE_220 = 1 << 220;
uint256 internal constant _ROLE_221 = 1 << 221;
uint256 internal constant _ROLE_222 = 1 << 222;
uint256 internal constant _ROLE_223 = 1 << 223;
uint256 internal constant _ROLE_224 = 1 << 224;
uint256 internal constant _ROLE_225 = 1 << 225;
uint256 internal constant _ROLE_226 = 1 << 226;
uint256 internal constant _ROLE_227 = 1 << 227;
uint256 internal constant _ROLE_228 = 1 << 228;
uint256 internal constant _ROLE_229 = 1 << 229;
uint256 internal constant _ROLE_230 = 1 << 230;
uint256 internal constant _ROLE_231 = 1 << 231;
uint256 internal constant _ROLE_232 = 1 << 232;
uint256 internal constant _ROLE_233 = 1 << 233;
uint256 internal constant _ROLE_234 = 1 << 234;
uint256 internal constant _ROLE_235 = 1 << 235;
uint256 internal constant _ROLE_236 = 1 << 236;
uint256 internal constant _ROLE_237 = 1 << 237;
uint256 internal constant _ROLE_238 = 1 << 238;
uint256 internal constant _ROLE_239 = 1 << 239;
uint256 internal constant _ROLE_240 = 1 << 240;
uint256 internal constant _ROLE_241 = 1 << 241;
uint256 internal constant _ROLE_242 = 1 << 242;
uint256 internal constant _ROLE_243 = 1 << 243;
uint256 internal constant _ROLE_244 = 1 << 244;
uint256 internal constant _ROLE_245 = 1 << 245;
uint256 internal constant _ROLE_246 = 1 << 246;
uint256 internal constant _ROLE_247 = 1 << 247;
uint256 internal constant _ROLE_248 = 1 << 248;
uint256 internal constant _ROLE_249 = 1 << 249;
uint256 internal constant _ROLE_250 = 1 << 250;
uint256 internal constant _ROLE_251 = 1 << 251;
uint256 internal constant _ROLE_252 = 1 << 252;
uint256 internal constant _ROLE_253 = 1 << 253;
uint256 internal constant _ROLE_254 = 1 << 254;
uint256 internal constant _ROLE_255 = 1 << 255;
}// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs
pragma solidity ^0.8.4;
/**
* @dev Interface of ERC721A.
*/
interface IERC721AUpgradeable {
/**
* The caller must own the token or be an approved operator.
*/
error ApprovalCallerNotOwnerNorApproved();
/**
* The token does not exist.
*/
error ApprovalQueryForNonexistentToken();
/**
* Cannot query the balance for the zero address.
*/
error BalanceQueryForZeroAddress();
/**
* Cannot mint to the zero address.
*/
error MintToZeroAddress();
/**
* The quantity of tokens minted must be more than zero.
*/
error MintZeroQuantity();
/**
* The token does not exist.
*/
error OwnerQueryForNonexistentToken();
/**
* The caller must own the token or be an approved operator.
*/
error TransferCallerNotOwnerNorApproved();
/**
* The token must be owned by `from`.
*/
error TransferFromIncorrectOwner();
/**
* Cannot safely transfer to a contract that does not implement the
* ERC721Receiver interface.
*/
error TransferToNonERC721ReceiverImplementer();
/**
* Cannot transfer to the zero address.
*/
error TransferToZeroAddress();
/**
* The token does not exist.
*/
error URIQueryForNonexistentToken();
/**
* The `quantity` minted with ERC2309 exceeds the safety limit.
*/
error MintERC2309QuantityExceedsLimit();
/**
* The `extraData` cannot be set on an unintialized ownership slot.
*/
error OwnershipNotInitializedForExtraData();
// =============================================================
// STRUCTS
// =============================================================
struct TokenOwnership {
// The address of the owner.
address addr;
// Stores the start time of ownership with minimal overhead for tokenomics.
uint64 startTimestamp;
// Whether the token has been burned.
bool burned;
// Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
uint24 extraData;
}
// =============================================================
// TOKEN COUNTERS
// =============================================================
/**
* @dev Returns the total number of tokens in existence.
* Burned tokens will reduce the count.
* To get the total number of tokens minted, please see {_totalMinted}.
*/
function totalSupply() external view returns (uint256);
// =============================================================
// IERC165
// =============================================================
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
// =============================================================
// IERC721
// =============================================================
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables
* (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in `owner`'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`,
* checking first that contract recipients are aware of the ERC721 protocol
* to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move
* this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement
* {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external payable;
/**
* @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @dev Transfers `tokenId` from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom}
* whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token
* by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the
* zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external payable;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom}
* for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
// =============================================================
// IERC721Metadata
// =============================================================
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
// =============================================================
// IERC2309
// =============================================================
/**
* @dev Emitted when tokens in `fromTokenId` to `toTokenId`
* (inclusive) is transferred from `from` to `to`, as defined in the
* [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
*
* See {_mintERC2309} for more details.
*/
event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)
pragma solidity ^0.8.0;
import "../utils/introspection/IERC165Upgradeable.sol";
/**
* @dev Interface for the NFT Royalty Standard.
*
* A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
* support for royalty payments across all NFT marketplaces and ecosystem participants.
*
* _Available since v4.5._
*/
interface IERC2981Upgradeable is IERC165Upgradeable {
/**
* @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
* exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
*/
function royaltyInfo(uint256 tokenId, uint256 salePrice)
external
view
returns (address receiver, uint256 royaltyAmount);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165Upgradeable {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
/// @dev While the ownable portion follows [EIP-173](https://eips.ethereum.org/EIPS/eip-173)
/// for compatibility, the nomenclature for the 2-step ownership handover
/// may be unique to this codebase.
abstract contract Ownable {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The caller is not authorized to call the function.
error Unauthorized();
/// @dev The `newOwner` cannot be the zero address.
error NewOwnerIsZeroAddress();
/// @dev The `pendingOwner` does not have a valid handover request.
error NoHandoverRequest();
/// @dev `bytes4(keccak256(bytes("Unauthorized()")))`.
uint256 private constant _UNAUTHORIZED_ERROR_SELECTOR = 0x82b42900;
/// @dev `bytes4(keccak256(bytes("NewOwnerIsZeroAddress()")))`.
uint256 private constant _NEW_OWNER_IS_ZERO_ADDRESS_ERROR_SELECTOR = 0x7448fbae;
/// @dev `bytes4(keccak256(bytes("NoHandoverRequest()")))`.
uint256 private constant _NO_HANDOVER_REQUEST_ERROR_SELECTOR = 0x6f5e8818;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EVENTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The ownership is transferred from `oldOwner` to `newOwner`.
/// This event is intentionally kept the same as OpenZeppelin's Ownable to be
/// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
/// despite it not being as lightweight as a single argument event.
event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
/// @dev An ownership handover to `pendingOwner` has been requested.
event OwnershipHandoverRequested(address indexed pendingOwner);
/// @dev The ownership handover to `pendingOwner` has been canceled.
event OwnershipHandoverCanceled(address indexed pendingOwner);
/// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;
/// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;
/// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STORAGE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The owner slot is given by: `not(_OWNER_SLOT_NOT)`.
/// It is intentionally choosen to be a high value
/// to avoid collision with lower slots.
/// The choice of manual storage layout is to enable compatibility
/// with both regular and upgradeable contracts.
uint256 private constant _OWNER_SLOT_NOT = 0x8b78c6d8;
/// The ownership handover slot of `newOwner` is given by:
/// ```
/// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
/// let handoverSlot := keccak256(0x00, 0x20)
/// ```
/// It stores the expiry timestamp of the two-step ownership handover.
uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Initializes the owner directly without authorization guard.
/// This function must be called upon initialization,
/// regardless of whether the contract is upgradeable or not.
/// This is to enable generalization to both regular and upgradeable contracts,
/// and to save gas in case the initial owner is not the caller.
/// For performance reasons, this function will not check if there
/// is an existing owner.
function _initializeOwner(address newOwner) internal virtual {
/// @solidity memory-safe-assembly
assembly {
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Store the new value.
sstore(not(_OWNER_SLOT_NOT), newOwner)
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
}
/// @dev Sets the owner directly without authorization guard.
function _setOwner(address newOwner) internal virtual {
/// @solidity memory-safe-assembly
assembly {
let ownerSlot := not(_OWNER_SLOT_NOT)
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
// Store the new value.
sstore(ownerSlot, newOwner)
}
}
/// @dev Throws if the sender is not the owner.
function _checkOwner() internal view virtual {
/// @solidity memory-safe-assembly
assembly {
// If the caller is not the stored owner, revert.
if iszero(eq(caller(), sload(not(_OWNER_SLOT_NOT)))) {
mstore(0x00, _UNAUTHORIZED_ERROR_SELECTOR)
revert(0x1c, 0x04)
}
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PUBLIC UPDATE FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Allows the owner to transfer the ownership to `newOwner`.
function transferOwnership(address newOwner) public payable virtual onlyOwner {
/// @solidity memory-safe-assembly
assembly {
if iszero(shl(96, newOwner)) {
mstore(0x00, _NEW_OWNER_IS_ZERO_ADDRESS_ERROR_SELECTOR)
revert(0x1c, 0x04)
}
}
_setOwner(newOwner);
}
/// @dev Allows the owner to renounce their ownership.
function renounceOwnership() public payable virtual onlyOwner {
_setOwner(address(0));
}
/// @dev Request a two-step ownership handover to the caller.
/// The request will be automatically expire in 48 hours (172800 seconds) by default.
function requestOwnershipHandover() public payable virtual {
unchecked {
uint256 expires = block.timestamp + ownershipHandoverValidFor();
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to `expires`.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), expires)
// Emit the {OwnershipHandoverRequested} event.
log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
}
}
}
/// @dev Cancels the two-step ownership handover to the caller, if any.
function cancelOwnershipHandover() public payable virtual {
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to 0.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), 0)
// Emit the {OwnershipHandoverCanceled} event.
log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
}
}
/// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
/// Reverts if there is no existing ownership handover requested by `pendingOwner`.
function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to 0.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
let handoverSlot := keccak256(0x0c, 0x20)
// If the handover does not exist, or has expired.
if gt(timestamp(), sload(handoverSlot)) {
mstore(0x00, _NO_HANDOVER_REQUEST_ERROR_SELECTOR)
revert(0x1c, 0x04)
}
// Set the handover slot to 0.
sstore(handoverSlot, 0)
}
_setOwner(pendingOwner);
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PUBLIC READ FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the owner of the contract.
function owner() public view virtual returns (address result) {
/// @solidity memory-safe-assembly
assembly {
result := sload(not(_OWNER_SLOT_NOT))
}
}
/// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
function ownershipHandoverExpiresAt(address pendingOwner)
public
view
virtual
returns (uint256 result)
{
/// @solidity memory-safe-assembly
assembly {
// Compute the handover slot.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
// Load the handover slot.
result := sload(keccak256(0x0c, 0x20))
}
}
/// @dev Returns how long a two-step ownership handover is valid for in seconds.
function ownershipHandoverValidFor() public view virtual returns (uint64) {
return 48 * 3600;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* MODIFIERS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Marks a function as only callable by the owner.
modifier onlyOwner() virtual {
_checkOwner();
_;
}
}{
"remappings": [
"@core/=contracts/core/",
"@modules/=contracts/modules/",
"ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",
"chiru-labs/ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",
"closedsea/=lib/closedsea/src/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/closedsea/lib/openzeppelin-contracts/lib/erc4626-tests/",
"erc721a-upgradeable/=lib/closedsea/lib/erc721a-upgradeable/contracts/",
"erc721a/=lib/closedsea/lib/erc721a/contracts/",
"forge-std/=lib/forge-std/src/",
"multicaller/=lib/multicaller/src/",
"murky/=lib/murky/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"openzeppelin/=lib/openzeppelin-contracts/contracts/",
"operator-filter-registry/=lib/closedsea/lib/operator-filter-registry/",
"preapprove/=lib/preapprove/src/",
"solady/=lib/solady/src/",
"solmate/=lib/solady/lib/solmate/src/"
],
"optimizer": {
"enabled": true,
"runs": 1000
},
"metadata": {
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"evmVersion": "paris",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_soundEditionImplementation","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayLengthsMismatch","type":"error"},{"inputs":[],"name":"ImplementationAddressCantBeZero","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"roles","type":"uint256"}],"name":"RolesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"soundEdition","type":"address"},{"indexed":true,"internalType":"address","name":"deployer","type":"address"},{"indexed":false,"internalType":"bytes","name":"initData","type":"bytes"},{"indexed":false,"internalType":"address[]","name":"contracts","type":"address[]"},{"indexed":false,"internalType":"bytes[]","name":"data","type":"bytes[]"},{"indexed":false,"internalType":"bytes[]","name":"results","type":"bytes[]"}],"name":"SoundEditionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newImplementation","type":"address"}],"name":"SoundEditionImplementationSet","type":"event"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initData","type":"bytes"},{"internalType":"address[]","name":"contracts","type":"address[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"createSoundAndMints","outputs":[{"internalType":"address","name":"soundEdition","type":"address"},{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"roles","type":"uint256"}],"name":"grantRoles","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"roles","type":"uint256"}],"name":"hasAllRoles","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"roles","type":"uint256"}],"name":"hasAnyRole","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"roles","type":"uint256"}],"name":"ordinalsFromRoles","outputs":[{"internalType":"uint8[]","name":"ordinals","type":"uint8[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownershipHandoverValidFor","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"roles","type":"uint256"}],"name":"renounceRoles","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"roles","type":"uint256"}],"name":"revokeRoles","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8[]","name":"ordinals","type":"uint8[]"}],"name":"rolesFromOrdinals","outputs":[{"internalType":"uint256","name":"roles","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"rolesOf","outputs":[{"internalType":"uint256","name":"roles","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"setEditionImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"by","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"soundEditionAddress","outputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"soundEditionImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b506040516110e33803806110e383398101604081905261002f916100be565b806001600160a01b03811661005757604051639841ec5160e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03841617905561007b33610082565b50506100ee565b6001600160a01b0316638b78c6d8198190558060007f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b6000602082840312156100d057600080fd5b81516001600160a01b03811681146100e757600080fd5b9392505050565b610fe6806100fd6000396000f3fe60806040526004361061015f5760003560e01c806354d1f13d116100c0578063a77e0b9811610074578063f04e283e11610059578063f04e283e146103c0578063f2fde38b146103d3578063fee81cf4146103e657600080fd5b8063a77e0b9814610382578063d7533f02146103a257600080fd5b806371537cdd116100a557806371537cdd146103085780637359e41f146103285780638da5cb5b1461035557600080fd5b806354d1f13d146102f8578063715018a61461030057600080fd5b80632de94807116101175780634a4ee7b1116100fc5780634a4ee7b11461026f5780635004b7a014610282578063514e62fc146102c157600080fd5b80632de948071461020e5780633d1d406a1461024157600080fd5b80631c10893f116101485780631c10893f146101ac5780631cd64df4146101bf578063256929621461020657600080fd5b806313a661ed14610164578063183a4f6e14610197575b600080fd5b34801561017057600080fd5b5061018461017f366004610b29565b610419565b6040519081526020015b60405180910390f35b6101aa6101a5366004610bee565b610442565b005b6101aa6101ba366004610c1e565b61044f565b3480156101cb57600080fd5b506101f66101da366004610c1e565b638b78c6d8600c90815260009290925260209091205481161490565b604051901515815260200161018e565b6101aa610465565b34801561021a57600080fd5b50610184610229366004610c48565b638b78c6d8600c908152600091909152602090205490565b34801561024d57600080fd5b5061026161025c366004610cb6565b6104b5565b60405161018e929190610e0d565b6101aa61027d366004610c1e565b6105e8565b34801561028e57600080fd5b506102a261029d366004610c1e565b6105fa565b604080516001600160a01b03909316835290151560208301520161018e565b3480156102cd57600080fd5b506101f66102dc366004610c1e565b638b78c6d8600c90815260009290925260209091205416151590565b6101aa6106ac565b6101aa6106e8565b34801561031457600080fd5b506101aa610323366004610c48565b6106fc565b34801561033457600080fd5b50610348610343366004610bee565b6107b2565b60405161018e9190610e37565b34801561036157600080fd5b50638b78c6d819545b6040516001600160a01b03909116815260200161018e565b34801561038e57600080fd5b5060005461036a906001600160a01b031681565b3480156103ae57600080fd5b506040516202a300815260200161018e565b6101aa6103ce366004610c48565b6107eb565b6101aa6103e1366004610c48565b610828565b3480156103f257600080fd5b50610184610401366004610c48565b63389a75e1600c908152600091909152602090205490565b6000815160051b5b801561043c57828101516001901b90911790601f1901610421565b50919050565b61044c338261084f565b50565b61045761089e565b61046182826108b9565b5050565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b600080546060906104e2906001600160a01b03166104dd338c60009182526020526040902090565b610904565b91506040518789823760008089836000875af1610503573d6000803e3d6000fd5b50610510868686866109df565b6040517ff2fde38b0000000000000000000000000000000000000000000000000000000081523360048201529091506001600160a01b0383169063f2fde38b90602401600060405180830381600087803b15801561056d57600080fd5b505af1158015610581573d6000803e3d6000fd5b50505050336001600160a01b0316826001600160a01b03167f405098db99342b699216d8150e930dbbf2f686f5a43485aed1e69219dafd49358a8a8a8a8a8a896040516105d49796959493929190610ea7565b60405180910390a397509795505050505050565b6105f061089e565b610461828261084f565b600080548190610696906001600160a01b0316610621868660009182526020526040902090565b306040517f3d602d80600a3d3981f3363d3d373d3d3d363d730000000000000000000000008152606093841b60148201527f5af43d82803e903d91602b57fd5bf3ff000000000000000000000000000000006028820152921b6038830152604c8201526037808220606c830152605591012090565b946001600160a01b0386163b1515945092505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b6106f061089e565b6106fa6000610aa6565b565b61070461089e565b806001600160a01b038116610745576040517f9841ec5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384169081179091556040519081527f6474a145358de2983a1f98097b7806fd7071e8ca712d3fa4f91df709a99a9c109060200160405180910390a15050565b604051602081016000835b81835260051b6020169091019060010183811c806107bd575050601f198282030160051c8252604052919050565b6107f361089e565b63389a75e1600c52806000526020600c20805442111561081b57636f5e88186000526004601cfd5b6000905561044c81610aa6565b61083061089e565b8060601b61084657637448fbae6000526004601cfd5b61044c81610aa6565b638b78c6d8600c52816000526020600c20805482811681189250508181555080600c5160601c7f715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26600080a35050565b638b78c6d8195433146106fa576382b429006000526004601cfd5b638b78c6d8600c52816000526020600c208181541791508181555080600c5160601c7f715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26600080a35050565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528360601b60148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f59150506001600160a01b0381166109d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f455243313136373a2063726561746532206661696c6564000000000000000000604482015260640160405180910390fd5b92915050565b6060838214610a1a576040517f3b800a4600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040519050818152602081018260051b84018360051b8201855b828114610a97578035870180356020820184378782038a01356000808335866000855af1610a66573d6000803e3d6000fd5b50508184526020840193503d82523d6000602084013e3d91909101603f0167ffffffffffffffe01690602001610a34565b50604052509095945050505050565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b803560ff81168114610b2457600080fd5b919050565b60006020808385031215610b3c57600080fd5b823567ffffffffffffffff80821115610b5457600080fd5b818501915085601f830112610b6857600080fd5b813581811115610b7a57610b7a610ae4565b8060051b604051601f19603f83011681018181108582111715610b9f57610b9f610ae4565b604052918252848201925083810185019188831115610bbd57600080fd5b938501935b82851015610be257610bd385610b13565b84529385019392850192610bc2565b98975050505050505050565b600060208284031215610c0057600080fd5b5035919050565b80356001600160a01b0381168114610b2457600080fd5b60008060408385031215610c3157600080fd5b610c3a83610c07565b946020939093013593505050565b600060208284031215610c5a57600080fd5b610c6382610c07565b9392505050565b60008083601f840112610c7c57600080fd5b50813567ffffffffffffffff811115610c9457600080fd5b6020830191508360208260051b8501011115610caf57600080fd5b9250929050565b60008060008060008060006080888a031215610cd157600080fd5b87359650602088013567ffffffffffffffff80821115610cf057600080fd5b818a0191508a601f830112610d0457600080fd5b813581811115610d1357600080fd5b8b6020828501011115610d2557600080fd5b6020830198508097505060408a0135915080821115610d4357600080fd5b610d4f8b838c01610c6a565b909650945060608a0135915080821115610d6857600080fd5b50610d758a828b01610c6a565b989b979a50959850939692959293505050565b600081518084526020808501808196508360051b810191508286016000805b86811015610dff578385038a5282518051808752835b81811015610dd8578281018901518882018a01528801610dbd565b5086810188018490529a87019a601f01601f19169095018601945091850191600101610da7565b509298975050505050505050565b6001600160a01b0383168152604060208201526000610e2f6040830184610d88565b949350505050565b6020808252825182820181905260009190848201906040850190845b81811015610e7257835160ff1683529284019291840191600101610e53565b50909695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b608081526000610ebb60808301898b610e7e565b8281036020848101919091528782528891810160005b89811015610efd576001600160a01b03610eea85610c07565b1682529282019290820190600101610ed1565b5084810360408601528681528181019250600587901b810182018860005b89811015610f8b57838303601f190186528135368c9003601e19018112610f4157600080fd5b8b01858101903567ffffffffffffffff811115610f5d57600080fd5b803603821315610f6c57600080fd5b610f77858284610e7e565b978701979450505090840190600101610f1b565b50508581036060870152610f9f8188610d88565b9d9c5050505050505050505050505056fea26469706673582212202902e8074694b93e609980d72ba92fee62906fc0199af1cdd0381427cc7b242164736f6c6343000813003300000000000000000000000000000000ee37e4f29070cab8c6a73cb43f2dd73d
Deployed Bytecode
0x60806040526004361061015f5760003560e01c806354d1f13d116100c0578063a77e0b9811610074578063f04e283e11610059578063f04e283e146103c0578063f2fde38b146103d3578063fee81cf4146103e657600080fd5b8063a77e0b9814610382578063d7533f02146103a257600080fd5b806371537cdd116100a557806371537cdd146103085780637359e41f146103285780638da5cb5b1461035557600080fd5b806354d1f13d146102f8578063715018a61461030057600080fd5b80632de94807116101175780634a4ee7b1116100fc5780634a4ee7b11461026f5780635004b7a014610282578063514e62fc146102c157600080fd5b80632de948071461020e5780633d1d406a1461024157600080fd5b80631c10893f116101485780631c10893f146101ac5780631cd64df4146101bf578063256929621461020657600080fd5b806313a661ed14610164578063183a4f6e14610197575b600080fd5b34801561017057600080fd5b5061018461017f366004610b29565b610419565b6040519081526020015b60405180910390f35b6101aa6101a5366004610bee565b610442565b005b6101aa6101ba366004610c1e565b61044f565b3480156101cb57600080fd5b506101f66101da366004610c1e565b638b78c6d8600c90815260009290925260209091205481161490565b604051901515815260200161018e565b6101aa610465565b34801561021a57600080fd5b50610184610229366004610c48565b638b78c6d8600c908152600091909152602090205490565b34801561024d57600080fd5b5061026161025c366004610cb6565b6104b5565b60405161018e929190610e0d565b6101aa61027d366004610c1e565b6105e8565b34801561028e57600080fd5b506102a261029d366004610c1e565b6105fa565b604080516001600160a01b03909316835290151560208301520161018e565b3480156102cd57600080fd5b506101f66102dc366004610c1e565b638b78c6d8600c90815260009290925260209091205416151590565b6101aa6106ac565b6101aa6106e8565b34801561031457600080fd5b506101aa610323366004610c48565b6106fc565b34801561033457600080fd5b50610348610343366004610bee565b6107b2565b60405161018e9190610e37565b34801561036157600080fd5b50638b78c6d819545b6040516001600160a01b03909116815260200161018e565b34801561038e57600080fd5b5060005461036a906001600160a01b031681565b3480156103ae57600080fd5b506040516202a300815260200161018e565b6101aa6103ce366004610c48565b6107eb565b6101aa6103e1366004610c48565b610828565b3480156103f257600080fd5b50610184610401366004610c48565b63389a75e1600c908152600091909152602090205490565b6000815160051b5b801561043c57828101516001901b90911790601f1901610421565b50919050565b61044c338261084f565b50565b61045761089e565b61046182826108b9565b5050565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b600080546060906104e2906001600160a01b03166104dd338c60009182526020526040902090565b610904565b91506040518789823760008089836000875af1610503573d6000803e3d6000fd5b50610510868686866109df565b6040517ff2fde38b0000000000000000000000000000000000000000000000000000000081523360048201529091506001600160a01b0383169063f2fde38b90602401600060405180830381600087803b15801561056d57600080fd5b505af1158015610581573d6000803e3d6000fd5b50505050336001600160a01b0316826001600160a01b03167f405098db99342b699216d8150e930dbbf2f686f5a43485aed1e69219dafd49358a8a8a8a8a8a896040516105d49796959493929190610ea7565b60405180910390a397509795505050505050565b6105f061089e565b610461828261084f565b600080548190610696906001600160a01b0316610621868660009182526020526040902090565b306040517f3d602d80600a3d3981f3363d3d373d3d3d363d730000000000000000000000008152606093841b60148201527f5af43d82803e903d91602b57fd5bf3ff000000000000000000000000000000006028820152921b6038830152604c8201526037808220606c830152605591012090565b946001600160a01b0386163b1515945092505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b6106f061089e565b6106fa6000610aa6565b565b61070461089e565b806001600160a01b038116610745576040517f9841ec5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384169081179091556040519081527f6474a145358de2983a1f98097b7806fd7071e8ca712d3fa4f91df709a99a9c109060200160405180910390a15050565b604051602081016000835b81835260051b6020169091019060010183811c806107bd575050601f198282030160051c8252604052919050565b6107f361089e565b63389a75e1600c52806000526020600c20805442111561081b57636f5e88186000526004601cfd5b6000905561044c81610aa6565b61083061089e565b8060601b61084657637448fbae6000526004601cfd5b61044c81610aa6565b638b78c6d8600c52816000526020600c20805482811681189250508181555080600c5160601c7f715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26600080a35050565b638b78c6d8195433146106fa576382b429006000526004601cfd5b638b78c6d8600c52816000526020600c208181541791508181555080600c5160601c7f715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26600080a35050565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528360601b60148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f59150506001600160a01b0381166109d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f455243313136373a2063726561746532206661696c6564000000000000000000604482015260640160405180910390fd5b92915050565b6060838214610a1a576040517f3b800a4600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040519050818152602081018260051b84018360051b8201855b828114610a97578035870180356020820184378782038a01356000808335866000855af1610a66573d6000803e3d6000fd5b50508184526020840193503d82523d6000602084013e3d91909101603f0167ffffffffffffffe01690602001610a34565b50604052509095945050505050565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b803560ff81168114610b2457600080fd5b919050565b60006020808385031215610b3c57600080fd5b823567ffffffffffffffff80821115610b5457600080fd5b818501915085601f830112610b6857600080fd5b813581811115610b7a57610b7a610ae4565b8060051b604051601f19603f83011681018181108582111715610b9f57610b9f610ae4565b604052918252848201925083810185019188831115610bbd57600080fd5b938501935b82851015610be257610bd385610b13565b84529385019392850192610bc2565b98975050505050505050565b600060208284031215610c0057600080fd5b5035919050565b80356001600160a01b0381168114610b2457600080fd5b60008060408385031215610c3157600080fd5b610c3a83610c07565b946020939093013593505050565b600060208284031215610c5a57600080fd5b610c6382610c07565b9392505050565b60008083601f840112610c7c57600080fd5b50813567ffffffffffffffff811115610c9457600080fd5b6020830191508360208260051b8501011115610caf57600080fd5b9250929050565b60008060008060008060006080888a031215610cd157600080fd5b87359650602088013567ffffffffffffffff80821115610cf057600080fd5b818a0191508a601f830112610d0457600080fd5b813581811115610d1357600080fd5b8b6020828501011115610d2557600080fd5b6020830198508097505060408a0135915080821115610d4357600080fd5b610d4f8b838c01610c6a565b909650945060608a0135915080821115610d6857600080fd5b50610d758a828b01610c6a565b989b979a50959850939692959293505050565b600081518084526020808501808196508360051b810191508286016000805b86811015610dff578385038a5282518051808752835b81811015610dd8578281018901518882018a01528801610dbd565b5086810188018490529a87019a601f01601f19169095018601945091850191600101610da7565b509298975050505050505050565b6001600160a01b0383168152604060208201526000610e2f6040830184610d88565b949350505050565b6020808252825182820181905260009190848201906040850190845b81811015610e7257835160ff1683529284019291840191600101610e53565b50909695505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b608081526000610ebb60808301898b610e7e565b8281036020848101919091528782528891810160005b89811015610efd576001600160a01b03610eea85610c07565b1682529282019290820190600101610ed1565b5084810360408601528681528181019250600587901b810182018860005b89811015610f8b57838303601f190186528135368c9003601e19018112610f4157600080fd5b8b01858101903567ffffffffffffffff811115610f5d57600080fd5b803603821315610f6c57600080fd5b610f77858284610e7e565b978701979450505090840190600101610f1b565b50508581036060870152610f9f8188610d88565b9d9c5050505050505050505050505056fea26469706673582212202902e8074694b93e609980d72ba92fee62906fc0199af1cdd0381427cc7b242164736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000ee37e4f29070cab8c6a73cb43f2dd73d
-----Decoded View---------------
Arg [0] : _soundEditionImplementation (address): 0x00000000ee37E4f29070cab8C6a73Cb43f2dD73d
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000ee37e4f29070cab8c6a73cb43f2dd73d
Deployed Bytecode Sourcemap
5555:8755:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9956:486:9;;;;;;;;;;-1:-1:-1;9956:486:9;;;;;:::i;:::-;;:::i;:::-;;;1632:25:10;;;1620:2;1605:18;9956:486:9;;;;;;;;7865:109;;;;;;:::i;:::-;;:::i;:::-;;7326:123;;;;;;:::i;:::-;;:::i;8885:437::-;;;;;;;;;;-1:-1:-1;8885:437:9;;;;;:::i;:::-;9104:15;9098:4;9091:29;;;8964:11;9133:18;;;;9284:4;9268:21;;;9262:28;9258:40;;9255:51;;8885:437;;;;2478:14:10;;2471:22;2453:41;;2441:2;2426:18;8885:437:9;2313:187:10;7253:616:8;;;:::i;9370:353:9:-;;;;;;;;;;-1:-1:-1;9370:353:9;;;;;:::i;:::-;9572:15;9566:4;9559:29;;;9430:13;9601:18;;;;9701:4;9685:21;;9679:28;;9370:353;6587:1559:0;;;;;;;;;;-1:-1:-1;6587:1559:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;7594:125:9:-;;;;;;:::i;:::-;;:::i;8738:268:0:-;;;;;;;;;;-1:-1:-1;8738:268:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;6235:55:10;;;6217:74;;6334:14;;6327:22;6322:2;6307:18;;6300:50;6190:18;8738:268:0;6049:307:10;8319:504:9;;;;;;;;;;-1:-1:-1;8319:504:9;;;;;:::i;:::-;8537:15;8531:4;8524:29;;;8397:11;8566:18;;;;8791:4;8775:21;;;8769:28;8765:40;8758:48;8751:56;;8319:504;7951:456:8;;;:::i;6991:100::-;;;:::i;8203:285:0:-;;;;;;;;;;-1:-1:-1;8203:285:0;;;;;:::i;:::-;;:::i;10677:1054:9:-;;;;;;;;;;-1:-1:-1;10677:1054:9;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;9638:191:8:-;;;;;;;;;;-1:-1:-1;;;9786:27:8;9638:191;;;-1:-1:-1;;;;;7169:55:10;;;7151:74;;7139:2;7124:18;9638:191:8;7005:226:10;5894:41:0;;;;;;;;;;-1:-1:-1;5894:41:0;;;;-1:-1:-1;;;;;5894:41:0;;;10458:107:8;;;;;;;;;;-1:-1:-1;10458:107:8;;10549:9;7380:50:10;;7368:2;7353:18;10458:107:8;7236:200:10;8594:707:8;;;;;;:::i;:::-;;:::i;6576:350::-;;;;;;:::i;:::-;;:::i;9932:435::-;;;;;;;;;;-1:-1:-1;9932:435:8;;;;;:::i;:::-;10202:19;10196:4;10189:33;;;10051:14;10235:26;;;;10345:4;10329:21;;10323:28;;9932:435;9956:486:9;10029:13;10148:8;10142:15;10139:1;10135:23;10120:306;10161:1;10120:306;;;10383:16;;;10377:23;10402:1;10373:31;;10370:42;;;;-1:-1:-1;;10170:12:9;10120:306;;;10124:36;9956:486;;;:::o;7865:109::-;7936:31;7949:10;7961:5;7936:12;:31::i;:::-;7865:109;:::o;7326:123::-;10954:13:8;:11;:13::i;:::-;7418:24:9::1;7430:4;7436:5;7418:11;:24::i;:::-;7326:123:::0;;:::o;7253:616:8:-;7346:15;10549:9;7364:45;;:15;:45;7346:63;;7577:19;7571:4;7564:33;7627:8;7621:4;7614:22;7683:7;7676:4;7670;7660:21;7653:38;7830:8;7783:45;7780:1;7777;7772:67;7479:374;7253:616::o;6587:1559:0:-;6764:20;6908:26;;6786:22;;6882:84;;-1:-1:-1;;;;;6908:26:0;6936:29;6948:10;6960:4;13697:14;13805:16;;;13841:4;13834:18;13955:4;13939:21;;;13627:349;6936:29;6882:25;:84::i;:::-;6859:108;;7090:4;7084:11;7196:15;7179;7176:1;7163:49;7664:4;7608;7551:15;7509:1;7451;7390:12;7345:5;7319:396;7292:622;;7836:16;7830:4;7824;7809:44;7883:16;7877:4;7870:30;7292:622;;7944:31;7959:9;;7970:4;;7944:14;:31::i;:::-;7986:56;;;;;8031:10;7986:56;;;7151:74:10;7934:41:0;;-1:-1:-1;;;;;;7986:44:0;;;;;7124:18:10;;7986:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8092:10;-1:-1:-1;;;;;8058:81:0;8078:12;-1:-1:-1;;;;;8058:81:0;;8104:8;;8114:9;;8125:4;;8131:7;8058:81;;;;;;;;;;;;:::i;:::-;;;;;;;;6587:1559;;;;;;;;;;:::o;7594:125:9:-;10954:13:8;:11;:13::i;:::-;7687:25:9::1;7700:4;7706:5;7687:12;:25::i;8738:268:0:-:0;8816:12;8895:26;;8816:12;;8860:100;;-1:-1:-1;;;;;8895:26:0;8923:21;8935:2;8939:4;13697:14;13805:16;;;13841:4;13834:18;13955:4;13939:21;;;13627:349;8923:21;8954:4;2867::7;2861:11;2897:66;2885:79;;3004:4;3000:25;;;2993:4;2984:14;;2977:49;3062:66;3055:4;3046:14;;3039:90;3165:19;;3158:4;3149:14;;3142:43;3214:4;3205:14;;3198:28;3277:4;3262:20;;;3255:4;3246:14;;3239:44;3335:4;3319:14;;3309:31;;2609:747;8860:100:0;8853:107;-1:-1:-1;;;;;8979:16:0;;;:20;;;-1:-1:-1;8738:268:0;-1:-1:-1;;;8738:268:0:o;7951:456:8:-;8153:19;8147:4;8140:33;8199:8;8193:4;8186:22;8251:1;8244:4;8238;8228:21;8221:32;8382:8;8336:44;8333:1;8330;8325:66;7951:456::o;6991:100::-;10954:13;:11;:13::i;:::-;7063:21:::1;7081:1;7063:9;:21::i;:::-;6991:100::o:0;8203:285:0:-;10954:13:8;:11;:13::i;:::-;8329:17:0;-1:-1:-1;;;;;14196:28:0;::::1;14192:99;;14247:33;;;;;;;;;;;;;;14192:99;8362:26:::2;:46:::0;;;::::2;-1:-1:-1::0;;;;;8362:46:0;::::2;::::0;;::::2;::::0;;;8424:57:::2;::::0;7151:74:10;;;8424:57:0::2;::::0;7139:2:10;7124:18;8424:57:0::2;;;;;;;10977:1:8::1;8203:285:0::0;:::o;10677:1054:9:-;10911:4;10905:11;10954:4;10940:19;;10981:1;11182:5;11167:367;11213:14;;;11401:1;11397:17;;;11388:27;;;;11411:1;11437:9;11468:13;;;;11167:367;11498:22;-1:-1:-1;;;;11618:29:9;;;;11615:1;11611:37;11594:55;;11705:4;11698:17;11631:8;10677:1054;-1:-1:-1;10677:1054:9:o;8594:707:8:-;10954:13;:11;:13::i;:::-;8828:19:::1;8822:4;8815:33;8874:12;8868:4;8861:26;8936:4;8930;8920:21;9042:12;9036:19;9023:11;9020:36;9017:156;;;9088:35;9082:4;9075:49;9154:4;9148;9141:18;9017:156;9250:1;9229:23:::0;;9271::::1;9281:12:::0;9271:9:::1;:23::i;6576:350::-:0;10954:13;:11;:13::i;:::-;6748:8:::1;6744:2;6740:17;6730:151;;6790:41;6784:4;6777:55;6862:4;6856;6849:18;6730:151;6900:19;6910:8;6900:9;:19::i;3516:834:9:-:0;3711:15;3705:4;3698:29;3753:4;3747;3740:18;3803:4;3797;3787:21;3886:8;3880:15;4119:5;4105:12;4101:24;4087:12;4083:43;4074:52;;;4198:5;4188:8;4181:23;;4328:5;4320:4;4314:11;4310:2;4306:20;4274:30;4271:1;4268;4263:71;3516:834;;:::o;5855:361:8:-;-1:-1:-1;;6061:27:8;6051:8;6048:41;6038:162;;6122:28;6116:4;6109:42;6181:4;6175;6168:18;2759:621:9;2953:15;2947:4;2940:29;2995:4;2989;2982:18;3045:4;3039;3029:21;3156:5;3145:8;3139:15;3136:26;3127:35;;3228:5;3218:8;3211:23;;3358:5;3350:4;3344:11;3340:2;3336:20;3304:30;3301:1;3298;3293:71;2759:621;;:::o;1906:593:7:-;1990:16;2101:4;2095:11;2131:66;2126:3;2119:79;2244:14;2238:4;2234:25;2227:4;2222:3;2218:14;2211:49;2296:66;2289:4;2284:3;2280:14;2273:90;2410:4;2404;2399:3;2396:1;2388:27;2376:39;-1:-1:-1;;;;;;;2442:22:7;;2434:58;;;;;;;10018:2:10;2434:58:7;;;10000:21:10;10057:2;10037:18;;;10030:30;10096:25;10076:18;;;10069:53;10139:18;;2434:58:7;;;;;;;;1906:593;;;;:::o;9479:3795:0:-;9590:22;9632:31;;;9628:66;;9672:22;;;;;;;;;;;;;;9628:66;9930:4;9924:11;9913:22;;10030:11;10021:7;10014:28;10160:4;10151:7;10147:18;10372:11;10369:1;10365:19;10352:11;10348:37;10576:11;10573:1;10569:19;10553:14;10549:40;10709:11;10694:2450;10736:14;10733:1;10730:21;10694:2450;;10887:1;10874:15;10861:11;10857:33;11171:1;11158:15;11076:4;11073:1;11069:12;11010:1;10976:248;11570:11;11567:1;11563:19;11545:16;11541:42;11528:56;12094:4;12034;11973:1;11960:15;11887:1;11825;11779;11730:5;11700:449;11669:699;;12282:16;12276:4;12270;12255:44;12333:16;12327:4;12320:30;11669:699;;;12473:1;12457:14;12450:25;12530:4;12514:14;12510:25;12492:43;;12626:16;12623:1;12616:27;12751:16;12745:4;12738;12735:1;12731:12;12716:52;13085:16;13078:24;;;;13104:4;13074:35;13111:18;13070:60;;10767:4;10760:12;10694:2450;;;-1:-1:-1;13250:4:0;13243:15;-1:-1:-1;9479:3795:0;;;-1:-1:-1;;;;;9479:3795:0:o;5302:495:8:-;-1:-1:-1;;5678:16:8;;-1:-1:-1;;;;;5534:26:8;;;;;;5638:38;5635:1;;5627:78;5754:27;5302:495::o;14:184:10:-;66:77;63:1;56:88;163:4;160:1;153:15;187:4;184:1;177:15;203:156;269:20;;329:4;318:16;;308:27;;298:55;;349:1;346;339:12;298:55;203:156;;;:::o;364:1117::-;446:6;477:2;520;508:9;499:7;495:23;491:32;488:52;;;536:1;533;526:12;488:52;576:9;563:23;605:18;646:2;638:6;635:14;632:34;;;662:1;659;652:12;632:34;700:6;689:9;685:22;675:32;;745:7;738:4;734:2;730:13;726:27;716:55;;767:1;764;757:12;716:55;803:2;790:16;825:2;821;818:10;815:36;;;831:18;;:::i;:::-;877:2;874:1;870:10;909:2;903:9;972:2;968:7;963:2;959;955:11;951:25;943:6;939:38;1027:6;1015:10;1012:22;1007:2;995:10;992:18;989:46;986:72;;;1038:18;;:::i;:::-;1074:2;1067:22;1124:18;;;1158:15;;;;-1:-1:-1;1200:11:10;;;1196:20;;;1228:19;;;1225:39;;;1260:1;1257;1250:12;1225:39;1284:11;;;;1304:146;1320:6;1315:3;1312:15;1304:146;;;1386:21;1403:3;1386:21;:::i;:::-;1374:34;;1337:12;;;;1428;;;;1304:146;;;1469:6;364:1117;-1:-1:-1;;;;;;;;364:1117:10:o;1668:180::-;1727:6;1780:2;1768:9;1759:7;1755:23;1751:32;1748:52;;;1796:1;1793;1786:12;1748:52;-1:-1:-1;1819:23:10;;1668:180;-1:-1:-1;1668:180:10:o;1853:196::-;1921:20;;-1:-1:-1;;;;;1970:54:10;;1960:65;;1950:93;;2039:1;2036;2029:12;2054:254;2122:6;2130;2183:2;2171:9;2162:7;2158:23;2154:32;2151:52;;;2199:1;2196;2189:12;2151:52;2222:29;2241:9;2222:29;:::i;:::-;2212:39;2298:2;2283:18;;;;2270:32;;-1:-1:-1;;;2054:254:10:o;2505:186::-;2564:6;2617:2;2605:9;2596:7;2592:23;2588:32;2585:52;;;2633:1;2630;2623:12;2585:52;2656:29;2675:9;2656:29;:::i;:::-;2646:39;2505:186;-1:-1:-1;;;2505:186:10:o;2696:367::-;2759:8;2769:6;2823:3;2816:4;2808:6;2804:17;2800:27;2790:55;;2841:1;2838;2831:12;2790:55;-1:-1:-1;2864:20:10;;2907:18;2896:30;;2893:50;;;2939:1;2936;2929:12;2893:50;2976:4;2968:6;2964:17;2952:29;;3036:3;3029:4;3019:6;3016:1;3012:14;3004:6;3000:27;2996:38;2993:47;2990:67;;;3053:1;3050;3043:12;2990:67;2696:367;;;;;:::o;3068:1301::-;3230:6;3238;3246;3254;3262;3270;3278;3331:3;3319:9;3310:7;3306:23;3302:33;3299:53;;;3348:1;3345;3338:12;3299:53;3384:9;3371:23;3361:33;;3445:2;3434:9;3430:18;3417:32;3468:18;3509:2;3501:6;3498:14;3495:34;;;3525:1;3522;3515:12;3495:34;3563:6;3552:9;3548:22;3538:32;;3608:7;3601:4;3597:2;3593:13;3589:27;3579:55;;3630:1;3627;3620:12;3579:55;3670:2;3657:16;3696:2;3688:6;3685:14;3682:34;;;3712:1;3709;3702:12;3682:34;3757:7;3752:2;3743:6;3739:2;3735:15;3731:24;3728:37;3725:57;;;3778:1;3775;3768:12;3725:57;3809:2;3805;3801:11;3791:21;;3831:6;3821:16;;;3890:2;3879:9;3875:18;3862:32;3846:48;;3919:2;3909:8;3906:16;3903:36;;;3935:1;3932;3925:12;3903:36;3974:72;4038:7;4027:8;4016:9;4012:24;3974:72;:::i;:::-;4065:8;;-1:-1:-1;3948:98:10;-1:-1:-1;4153:2:10;4138:18;;4125:32;;-1:-1:-1;4169:16:10;;;4166:36;;;4198:1;4195;4188:12;4166:36;;4237:72;4301:7;4290:8;4279:9;4275:24;4237:72;:::i;:::-;3068:1301;;;;-1:-1:-1;3068:1301:10;;-1:-1:-1;3068:1301:10;;;;4211:98;;-1:-1:-1;;;3068:1301:10:o;4374:1009::-;4425:3;4463:5;4457:12;4490:6;4485:3;4478:19;4516:4;4557:2;4552:3;4548:12;4582:11;4609;4602:18;;4659:6;4656:1;4652:14;4645:5;4641:26;4629:38;;4701:2;4694:5;4690:14;4722:1;4743;4753:604;4769:6;4764:3;4761:15;4753:604;;;4844:5;4838:4;4834:16;4829:3;4822:29;4880:6;4874:13;4922:2;4916:9;4951:8;4945:4;4938:22;4984:1;4998:155;5014:8;5009:3;5006:17;4998:155;;;5120:12;;;5116:21;;5110:28;5089:14;;;5085:23;;5078:61;5033:12;;4998:155;;;-1:-1:-1;5177:19:10;;;5173:28;;5166:39;;;5335:12;;;;5267:2;5244:17;-1:-1:-1;;5240:31:10;5230:42;;;5226:51;;;-1:-1:-1;5300:15:10;;;;4795:1;4786:11;4753:604;;;-1:-1:-1;5373:4:10;;4374:1009;-1:-1:-1;;;;;;;;4374:1009:10:o;5388:397::-;-1:-1:-1;;;;;5617:6:10;5613:55;5602:9;5595:74;5705:2;5700;5689:9;5685:18;5678:30;5576:4;5725:54;5775:2;5764:9;5760:18;5752:6;5725:54;:::i;:::-;5717:62;5388:397;-1:-1:-1;;;;5388:397:10:o;6361:639::-;6528:2;6580:21;;;6650:13;;6553:18;;;6672:22;;;6499:4;;6528:2;6751:15;;;;6725:2;6710:18;;;6499:4;6794:180;6808:6;6805:1;6802:13;6794:180;;;6873:13;;6888:4;6869:24;6857:37;;6949:15;;;;6914:12;;;;6830:1;6823:9;6794:180;;;-1:-1:-1;6991:3:10;;6361:639;-1:-1:-1;;;;;;6361:639:10:o;7441:266::-;7529:6;7524:3;7517:19;7581:6;7574:5;7567:4;7562:3;7558:14;7545:43;-1:-1:-1;7633:1:10;7608:16;;;7626:4;7604:27;;;7597:38;;;;7689:2;7668:15;;;-1:-1:-1;;7664:29:10;7655:39;;;7651:50;;7441:266::o;7712:2099::-;8161:3;8150:9;8143:22;8124:4;8188:62;8245:3;8234:9;8230:19;8222:6;8214;8188:62;:::i;:::-;8307:22;;;8269:2;8287:18;;;8280:50;;;;8365:22;;;8441:6;;8403:15;;8465:1;8475:231;8489:6;8486:1;8483:13;8475:231;;;-1:-1:-1;;;;;8554:26:10;8573:6;8554:26;:::i;:::-;8550:75;8538:88;;8681:15;;;;8646:12;;;;8511:1;8504:9;8475:231;;;-1:-1:-1;8742:19:10;;;8737:2;8722:18;;8715:47;8796:19;;;8833:12;;;;-1:-1:-1;8885:1:10;8881:14;;;8872:24;;8868:33;;8926:6;8952:1;8962:725;8978:6;8973:3;8970:15;8962:725;;;9049:16;;;-1:-1:-1;;9045:30:10;9031:45;;9115:22;;9192:14;9188:27;;;-1:-1:-1;;9184:41:10;9160:66;;9150:94;;9240:1;9237;9230:12;9150:94;9270:31;;9375:14;;;;9328:19;9416:18;9405:30;;9402:50;;;9448:1;9445;9438:12;9402:50;9501:6;9485:14;9481:27;9472:7;9468:41;9465:61;;;9522:1;9519;9512:12;9465:61;9549:50;9592:6;9584;9575:7;9549:50;:::i;:::-;9663:14;;;;9539:60;-1:-1:-1;;;9624:17:10;;;;9004:1;8995:11;8962:725;;;8966:3;;9735:9;9727:6;9723:22;9718:2;9707:9;9703:18;9696:50;9763:42;9798:6;9790;9763:42;:::i;:::-;9755:50;7712:2099;-1:-1:-1;;;;;;;;;;;;;7712:2099:10:o
Swarm Source
ipfs://2902e8074694b93e609980d72ba92fee62906fc0199af1cdd0381427cc7b2421
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.