Overview
APE Balance
0 APE
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 5 from a total of 5 transactions
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
8590690 | 8 days ago | 0.01830289 APE |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
DookeyFlips
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.28; import {IEntropy} from "@pythnetwork/entropy-sdk-solidity/IEntropy.sol"; import {IEntropyConsumer} from "@pythnetwork/entropy-sdk-solidity/IEntropyConsumer.sol"; import {Ownable} from "solady/auth/Ownable.sol"; struct Tier { uint128 numberOfFlipsAssigned; uint128 maxNumberOfFlips; } contract DookeyFlips is IEntropyConsumer, Ownable { error InvalidTier(); error TierAlreadyAssigned(); error ArraysLengthMismatch(); error NoMoreTiers(); error MaxSupplyMismatch(); error RandomNumberAlreadySet(); error RandomNumberNotSet(); event FlipAssigned(uint256 indexed flipId, uint256 indexed tier); event TiersAssigned(uint256 indexed numberOfTiers); event EntropyRequested(uint256 indexed numberOfFlipsRequested); event RandomNumberSet(bytes32 indexed randomNumber); IEntropy public constant entropy = IEntropy(0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320); address public constant provider = 0x52DeaA1c84233F7bb8C8A45baeDE41091c616506; mapping(uint256 flipId => uint256 tierId) public flipIdToTierId; mapping(uint256 tokenIndex => uint256 tokenId) public tokenIndexToTokenId; mapping(uint256 tierId => Tier) public tierIdToTier; mapping(uint64 sequenceNumber => uint256 numberOfFlipsToAssign) public sequenceNumberToNumberOfFlipsToAssign; uint256 public immutable _MAX_SUPPLY; uint256 public currentTierToAssign; bytes32 public randomNumber; uint256 public nextFlipToAssign; uint256 public immutable _NUMBER_OF_TIERS; constructor(uint256 _numberOfTiers, uint256 _maxSupply) { _initializeOwner(msg.sender); _NUMBER_OF_TIERS = _numberOfTiers; _MAX_SUPPLY = _maxSupply; currentTierToAssign = _NUMBER_OF_TIERS; } function assignNumberOfFlipsToTier(uint128[] calldata numberOfFlips) external onlyOwner { if (numberOfFlips.length != _NUMBER_OF_TIERS) revert ArraysLengthMismatch(); uint256 totalNumberOfFlipsAssigned; for (uint256 i; i < numberOfFlips.length; i++) { // start at tier 1 if (tierIdToTier[i + 1].numberOfFlipsAssigned > 0) revert TierAlreadyAssigned(); tierIdToTier[i + 1] = Tier(0, numberOfFlips[i]); totalNumberOfFlipsAssigned += numberOfFlips[i]; } if (totalNumberOfFlipsAssigned != _MAX_SUPPLY) revert MaxSupplyMismatch(); emit TiersAssigned(_NUMBER_OF_TIERS); } function requestEntropy() external payable returns (uint64) { uint128 requestFee = entropy.getFee(provider); bytes32 pseudoRandomNumber = keccak256(abi.encode(block.timestamp, block.number, msg.sender)); uint64 sequenceNumber = entropy.requestWithCallback{value: requestFee}(provider, pseudoRandomNumber); emit EntropyRequested(sequenceNumber); return sequenceNumber; } function getFee() external view returns (uint128) { return entropy.getFee(provider); } function entropyCallback(uint64, address, bytes32 _randomNumber) internal override { if (randomNumber != 0) revert RandomNumberAlreadySet(); randomNumber = _randomNumber; emit RandomNumberSet(_randomNumber); } function assignFlips(uint256 numberOfFlipsToAssign) external { if (randomNumber == 0) revert RandomNumberNotSet(); for (uint256 i; i < numberOfFlipsToAssign; i++) { _assignFlipToTier(uint256(keccak256(abi.encode(randomNumber, i, provider)))); } unchecked { nextFlipToAssign += numberOfFlipsToAssign; } // reset random number to avoid re-use randomNumber = keccak256(abi.encode(block.timestamp, block.number, randomNumber)); } function _getTotalFlipsAssigned() internal view returns (uint256) { uint256 totalFlipsAssigned; for (uint256 i = _NUMBER_OF_TIERS; i > 0; i--) { totalFlipsAssigned += tierIdToTier[i].numberOfFlipsAssigned; // break if the tier is unfinished (number of flips assigned to a tier is less than the max number of flips) if (tierIdToTier[i].numberOfFlipsAssigned < tierIdToTier[i].maxNumberOfFlips) break; } return totalFlipsAssigned; } function _assignFlipToTier(uint256 _randomNumber) internal { if (currentTierToAssign == 0) revert NoMoreTiers(); // convert random number to token ID within max supply. uint256 maxIndex = _MAX_SUPPLY - _getTotalFlipsAssigned(); uint256 random = _randomNumber % maxIndex; uint256 tokenId = tokenIndexToTokenId[random]; if (tokenIndexToTokenId[random] == 0) { tokenId = random; } tokenIndexToTokenId[maxIndex - 1] == 0 ? tokenIndexToTokenId[random] = maxIndex - 1 : tokenIndexToTokenId[random] = tokenIndexToTokenId[maxIndex - 1]; flipIdToTierId[tokenId] = currentTierToAssign; unchecked { ++tierIdToTier[currentTierToAssign].numberOfFlipsAssigned; } if ( tierIdToTier[currentTierToAssign].numberOfFlipsAssigned == tierIdToTier[currentTierToAssign].maxNumberOfFlips ) { unchecked { --currentTierToAssign; } } emit FlipAssigned(tokenId, currentTierToAssign); } // This method is required by the IEntropyConsumer interface function getEntropy() internal view override returns (address) { return address(entropy); } }
// SPDX-License-Identifier: Apache 2 pragma solidity ^0.8.0; import "./EntropyEvents.sol"; interface IEntropy is EntropyEvents { // Register msg.sender as a randomness provider. The arguments are the provider's configuration parameters // and initial commitment. Re-registering the same provider rotates the provider's commitment (and updates // the feeInWei). // // chainLength is the number of values in the hash chain *including* the commitment, that is, chainLength >= 1. function register( uint128 feeInWei, bytes32 commitment, bytes calldata commitmentMetadata, uint64 chainLength, bytes calldata uri ) external; // Withdraw a portion of the accumulated fees for the provider msg.sender. // Calling this function will transfer `amount` wei to the caller (provided that they have accrued a sufficient // balance of fees in the contract). function withdraw(uint128 amount) external; // Withdraw a portion of the accumulated fees for provider. The msg.sender must be the fee manager for this provider. // Calling this function will transfer `amount` wei to the caller (provided that they have accrued a sufficient // balance of fees in the contract). function withdrawAsFeeManager(address provider, uint128 amount) external; // As a user, request a random number from `provider`. Prior to calling this method, the user should // generate a random number x and keep it secret. The user should then compute hash(x) and pass that // as the userCommitment argument. (You may call the constructUserCommitment method to compute the hash.) // // This method returns a sequence number. The user should pass this sequence number to // their chosen provider (the exact method for doing so will depend on the provider) to retrieve the provider's // number. The user should then call fulfillRequest to construct the final random number. // // This method will revert unless the caller provides a sufficient fee (at least getFee(provider)) as msg.value. // Note that excess value is *not* refunded to the caller. function request( address provider, bytes32 userCommitment, bool useBlockHash ) external payable returns (uint64 assignedSequenceNumber); // Request a random number. The method expects the provider address and a secret random number // in the arguments. It returns a sequence number. // // The address calling this function should be a contract that inherits from the IEntropyConsumer interface. // The `entropyCallback` method on that interface will receive a callback with the generated random number. // // This method will revert unless the caller provides a sufficient fee (at least getFee(provider)) as msg.value. // Note that excess value is *not* refunded to the caller. function requestWithCallback( address provider, bytes32 userRandomNumber ) external payable returns (uint64 assignedSequenceNumber); // Fulfill a request for a random number. This method validates the provided userRandomness and provider's proof // against the corresponding commitments in the in-flight request. If both values are validated, this function returns // the corresponding random number. // // Note that this function can only be called once per in-flight request. Calling this function deletes the stored // request information (so that the contract doesn't use a linear amount of storage in the number of requests). // If you need to use the returned random number more than once, you are responsible for storing it. function reveal( address provider, uint64 sequenceNumber, bytes32 userRevelation, bytes32 providerRevelation ) external returns (bytes32 randomNumber); // Fulfill a request for a random number. This method validates the provided userRandomness // and provider's revelation against the corresponding commitment in the in-flight request. If both values are validated // and the requestor address is a contract address, this function calls the requester's entropyCallback method with the // sequence number, provider address and the random number as arguments. Else if the requestor is an EOA, it won't call it. // // Note that this function can only be called once per in-flight request. Calling this function deletes the stored // request information (so that the contract doesn't use a linear amount of storage in the number of requests). // If you need to use the returned random number more than once, you are responsible for storing it. // // Anyone can call this method to fulfill a request, but the callback will only be made to the original requester. function revealWithCallback( address provider, uint64 sequenceNumber, bytes32 userRandomNumber, bytes32 providerRevelation ) external; function getProviderInfo( address provider ) external view returns (EntropyStructs.ProviderInfo memory info); function getDefaultProvider() external view returns (address provider); function getRequest( address provider, uint64 sequenceNumber ) external view returns (EntropyStructs.Request memory req); function getFee(address provider) external view returns (uint128 feeAmount); function getAccruedPythFees() external view returns (uint128 accruedPythFeesInWei); function setProviderFee(uint128 newFeeInWei) external; function setProviderFeeAsFeeManager( address provider, uint128 newFeeInWei ) external; function setProviderUri(bytes calldata newUri) external; // Set manager as the fee manager for the provider msg.sender. // After calling this function, manager will be able to set the provider's fees and withdraw them. // Only one address can be the fee manager for a provider at a time -- calling this function again with a new value // will override the previous value. Call this function with the all-zero address to disable the fee manager role. function setFeeManager(address manager) external; function constructUserCommitment( bytes32 userRandomness ) external pure returns (bytes32 userCommitment); function combineRandomValues( bytes32 userRandomness, bytes32 providerRandomness, bytes32 blockHash ) external pure returns (bytes32 combinedRandomness); }
// SPDX-License-Identifier: Apache 2 pragma solidity ^0.8.0; abstract contract IEntropyConsumer { // This method is called by Entropy to provide the random number to the consumer. // It asserts that the msg.sender is the Entropy contract. It is not meant to be // override by the consumer. function _entropyCallback( uint64 sequence, address provider, bytes32 randomNumber ) external { address entropy = getEntropy(); require(entropy != address(0), "Entropy address not set"); require(msg.sender == entropy, "Only Entropy can call this function"); entropyCallback(sequence, provider, randomNumber); } // getEntropy returns Entropy contract address. The method is being used to check that the // callback is indeed from Entropy contract. The consumer is expected to implement this method. // Entropy address can be found here - https://docs.pyth.network/entropy/contract-addresses function getEntropy() internal view virtual returns (address); // This method is expected to be implemented by the consumer to handle the random number. // It will be called by _entropyCallback after _entropyCallback ensures that the call is // indeed from Entropy contract. function entropyCallback( uint64 sequence, address provider, bytes32 randomNumber ) internal virtual; }
// 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 Note: /// This implementation does NOT auto-initialize the owner to `msg.sender`. /// You MUST call the `_initializeOwner` in the constructor / initializer. /// /// 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 Cannot double-initialize. error AlreadyInitialized(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* 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: /// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`. /// It is intentionally chosen 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. bytes32 internal constant _OWNER_SLOT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927; /// 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 Override to return true to make `_initializeOwner` prevent double-initialization. function _guardInitializeOwner() internal pure virtual returns (bool guard) {} /// @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 { if (_guardInitializeOwner()) { /// @solidity memory-safe-assembly assembly { let ownerSlot := _OWNER_SLOT if sload(ownerSlot) { mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`. revert(0x1c, 0x04) } // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Store the new value. sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner)))) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner) } } else { /// @solidity memory-safe-assembly assembly { // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Store the new value. sstore(_OWNER_SLOT, 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 { if (_guardInitializeOwner()) { /// @solidity memory-safe-assembly assembly { let ownerSlot := _OWNER_SLOT // 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, or(newOwner, shl(255, iszero(newOwner)))) } } else { /// @solidity memory-safe-assembly assembly { let ownerSlot := _OWNER_SLOT // 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(_OWNER_SLOT))) { mstore(0x00, 0x82b42900) // `Unauthorized()`. revert(0x1c, 0x04) } } } /// @dev Returns how long a two-step ownership handover is valid for in seconds. /// Override to return a different value if needed. /// Made internal to conserve bytecode. Wrap it in a public function if needed. function _ownershipHandoverValidFor() internal view virtual returns (uint64) { return 48 * 3600; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* 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, 0x7448fbae) // `NewOwnerIsZeroAddress()`. 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 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, 0x6f5e8818) // `NoHandoverRequest()`. 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(_OWNER_SLOT) } } /// @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)) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MODIFIERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Marks a function as only callable by the owner. modifier onlyOwner() virtual { _checkOwner(); _; } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.0; import "./EntropyStructs.sol"; interface EntropyEvents { event Registered(EntropyStructs.ProviderInfo provider); event Requested(EntropyStructs.Request request); event RequestedWithCallback( address indexed provider, address indexed requestor, uint64 indexed sequenceNumber, bytes32 userRandomNumber, EntropyStructs.Request request ); event Revealed( EntropyStructs.Request request, bytes32 userRevelation, bytes32 providerRevelation, bytes32 blockHash, bytes32 randomNumber ); event RevealedWithCallback( EntropyStructs.Request request, bytes32 userRandomNumber, bytes32 providerRevelation, bytes32 randomNumber ); event ProviderFeeUpdated(address provider, uint128 oldFee, uint128 newFee); event ProviderUriUpdated(address provider, bytes oldUri, bytes newUri); event ProviderFeeManagerUpdated( address provider, address oldFeeManager, address newFeeManager ); event Withdrawal( address provider, address recipient, uint128 withdrawnAmount ); }
// SPDX-License-Identifier: Apache 2 pragma solidity ^0.8.0; contract EntropyStructs { struct ProviderInfo { uint128 feeInWei; uint128 accruedFeesInWei; // The commitment that the provider posted to the blockchain, and the sequence number // where they committed to this. This value is not advanced after the provider commits, // and instead is stored to help providers track where they are in the hash chain. bytes32 originalCommitment; uint64 originalCommitmentSequenceNumber; // Metadata for the current commitment. Providers may optionally use this field to help // manage rotations (i.e., to pick the sequence number from the correct hash chain). bytes commitmentMetadata; // Optional URI where clients can retrieve revelations for the provider. // Client SDKs can use this field to automatically determine how to retrieve random values for each provider. // TODO: specify the API that must be implemented at this URI bytes uri; // The first sequence number that is *not* included in the current commitment (i.e., an exclusive end index). // The contract maintains the invariant that sequenceNumber <= endSequenceNumber. // If sequenceNumber == endSequenceNumber, the provider must rotate their commitment to add additional random values. uint64 endSequenceNumber; // The sequence number that will be assigned to the next inbound user request. uint64 sequenceNumber; // The current commitment represents an index/value in the provider's hash chain. // These values are used to verify requests for future sequence numbers. Note that // currentCommitmentSequenceNumber < sequenceNumber. // // The currentCommitment advances forward through the provider's hash chain as values // are revealed on-chain. bytes32 currentCommitment; uint64 currentCommitmentSequenceNumber; // An address that is authorized to set / withdraw fees on behalf of this provider. address feeManager; } struct Request { // Storage slot 1 // address provider; uint64 sequenceNumber; // The number of hashes required to verify the provider revelation. uint32 numHashes; // Storage slot 2 // // The commitment is keccak256(userCommitment, providerCommitment). Storing the hash instead of both saves 20k gas by // eliminating 1 store. bytes32 commitment; // Storage slot 3 // // The number of the block where this request was created. // Note that we're using a uint64 such that we have an additional space for an address and other fields in // this storage slot. Although block.number returns a uint256, 64 bits should be plenty to index all of the // blocks ever generated. uint64 blockNumber; // The address that requested this random number. address requester; // If true, incorporate the blockhash of blockNumber into the generated random value. bool useBlockhash; // If true, the requester will be called back with the generated random value. bool isRequestWithCallback; // There are 2 remaining bytes of free space in this slot. } }
{ "remappings": [ "solady/=lib/solady/src/", "forge-std/=lib/forge-std/src/", "@pythnetwork/entropy-sdk-solidity/=node_modules/@pythnetwork/entropy-sdk-solidity/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint256","name":"_numberOfTiers","type":"uint256"},{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"ArraysLengthMismatch","type":"error"},{"inputs":[],"name":"InvalidTier","type":"error"},{"inputs":[],"name":"MaxSupplyMismatch","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"NoMoreTiers","type":"error"},{"inputs":[],"name":"RandomNumberAlreadySet","type":"error"},{"inputs":[],"name":"RandomNumberNotSet","type":"error"},{"inputs":[],"name":"TierAlreadyAssigned","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"numberOfFlipsRequested","type":"uint256"}],"name":"EntropyRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"flipId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"tier","type":"uint256"}],"name":"FlipAssigned","type":"event"},{"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":"bytes32","name":"randomNumber","type":"bytes32"}],"name":"RandomNumberSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"numberOfTiers","type":"uint256"}],"name":"TiersAssigned","type":"event"},{"inputs":[],"name":"_MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_NUMBER_OF_TIERS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"address","name":"provider","type":"address"},{"internalType":"bytes32","name":"randomNumber","type":"bytes32"}],"name":"_entropyCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfFlipsToAssign","type":"uint256"}],"name":"assignFlips","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128[]","name":"numberOfFlips","type":"uint128[]"}],"name":"assignNumberOfFlipsToTier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"currentTierToAssign","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"entropy","outputs":[{"internalType":"contract IEntropy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"flipId","type":"uint256"}],"name":"flipIdToTierId","outputs":[{"internalType":"uint256","name":"tierId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFee","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextFlipToAssign","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"provider","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomNumber","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestEntropy","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"sequenceNumber","type":"uint64"}],"name":"sequenceNumberToNumberOfFlipsToAssign","outputs":[{"internalType":"uint256","name":"numberOfFlipsToAssign","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tierId","type":"uint256"}],"name":"tierIdToTier","outputs":[{"internalType":"uint128","name":"numberOfFlipsAssigned","type":"uint128"},{"internalType":"uint128","name":"maxNumberOfFlips","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenIndex","type":"uint256"}],"name":"tokenIndexToTokenId","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60c060405234801561000f575f5ffd5b506040516110ec3803806110ec83398101604081905261002e91610082565b61003733610047565b60a08290526080526004556100a4565b6001600160a01b0316638b78c6d819819055805f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b5f5f60408385031215610093575f5ffd5b505080516020909101519092909150565b60805160a0516110046100e85f395f81816103c001528181610746015281816108ea0152610d2b01525f818161044f015281816108a70152610bcd01526110045ff3fe60806040526004361061013c575f3560e01c8063b13038a1116100b3578063f2fde38b1161006d578063f2fde38b1461037d578063f4eff48f14610390578063f5510d62146103af578063f7f73f3e146103e2578063fee81cf41461040d578063fffa65e01461043e575f5ffd5b8063b13038a11461028a578063b5c3dbbb146102ab578063c518435e1461030a578063ccbac9f514610329578063ced72f871461033e578063f04e283e1461036a575f5ffd5b806352a5f1f81161010457806352a5f1f81461020357806354d1f13d14610222578063715018a61461022a5780638a2a9a9d146102325780638da5cb5b1461025d5780639e24410514610275575f5ffd5b8063013c978e14610140578063085d48831461017e57806325692962146101bd578063475d39ff146101c757806347ce07cc146101dc575b5f5ffd5b34801561014b575f5ffd5b5061016b61015a366004610dc8565b60036020525f908152604090205481565b6040519081526020015b60405180910390f35b348015610189575f5ffd5b506101a57352deaa1c84233f7bb8c8a45baede41091c61650681565b6040516001600160a01b039091168152602001610175565b6101c5610471565b005b3480156101d2575f5ffd5b5061016b60065481565b3480156101e7575f5ffd5b506101a57336825bf3fbdf5a29e2d5148bfe7dcf7b5639e32081565b34801561020e575f5ffd5b506101c561021d366004610e05565b6104be565b6101c5610556565b6101c561058f565b34801561023d575f5ffd5b5061016b61024c366004610e40565b5f6020819052908152604090205481565b348015610268575f5ffd5b50638b78c6d819546101a5565b348015610280575f5ffd5b5061016b60045481565b6102926105a2565b60405167ffffffffffffffff9091168152602001610175565b3480156102b6575f5ffd5b506102ea6102c5366004610e40565b60026020525f90815260409020546001600160801b0380821691600160801b90041682565b604080516001600160801b03938416815292909116602083015201610175565b348015610315575f5ffd5b506101c5610324366004610e57565b61073c565b348015610334575f5ffd5b5061016b60055481565b348015610349575f5ffd5b50610352610934565b6040516001600160801b039091168152602001610175565b6101c5610378366004610ec8565b6109c0565b6101c561038b366004610ec8565b6109fd565b34801561039b575f5ffd5b506101c56103aa366004610e40565b610a23565b3480156103ba575f5ffd5b5061016b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103ed575f5ffd5b5061016b6103fc366004610e40565b60016020525f908152604090205481565b348015610418575f5ffd5b5061016b610427366004610ec8565b63389a75e1600c9081525f91909152602090205490565b348015610449575f5ffd5b5061016b7f000000000000000000000000000000000000000000000000000000000000000081565b5f6202a30067ffffffffffffffff164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f5fa250565b7336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3206104e1565b60405180910390fd5b336001600160a01b038216146105455760405162461bcd60e51b815260206004820152602360248201527f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460448201526234b7b760e91b60648201526084016104d8565b610550848484610af0565b50505050565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f5fa2565b610597610b45565b6105a05f610b5f565b565b604051631711922960e31b81527352deaa1c84233f7bb8c8a45baede41091c61650660048201525f9081907336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3209063b88c914890602401602060405180830381865afa158015610607573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061062b9190610ef5565b6040805142602082015243918101919091523360608201529091505f9060800160408051808303601f190181529082905280516020909101206319cb825f60e01b82527352deaa1c84233f7bb8c8a45baede41091c61650660048301526024820181905291505f907336825bf3fbdf5a29e2d5148bfe7dcf7b5639e320906319cb825f906001600160801b0386169060440160206040518083038185885af11580156106d9573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106fe9190610f10565b60405190915067ffffffffffffffff8216907f6ab4d3605438901c2c16d05ecddf4593282d86ff03bc92289aed71ec7ddb37f9905f90a29392505050565b610744610b45565b7f00000000000000000000000000000000000000000000000000000000000000008114610784576040516307e11acb60e51b815260040160405180910390fd5b5f5f5b828110156108a4575f60028161079e846001610f3f565b815260208101919091526040015f20546001600160801b031611156107d657604051635e241e5160e11b815260040160405180910390fd5b60405180604001604052805f6001600160801b0316815260200185858481811061080257610802610f58565b90506020020160208101906108179190610f6c565b6001600160801b0316905260025f610830846001610f3f565b81526020808201929092526040015f20825192909101516001600160801b03908116600160801b02921691909117905583838281811061087257610872610f58565b90506020020160208101906108879190610f6c565b61089a906001600160801b031683610f3f565b9150600101610787565b507f000000000000000000000000000000000000000000000000000000000000000081146108e557604051633bb0d26f60e21b815260040160405180910390fd5b6040517f0000000000000000000000000000000000000000000000000000000000000000907fdd39ce343fdf5e27b865f30c5372b4c57b221382dc6bec00a617dc05663814f3905f90a2505050565b604051631711922960e31b81527352deaa1c84233f7bb8c8a45baede41091c61650660048201525f907336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3209063b88c914890602401602060405180830381865afa158015610997573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109bb9190610ef5565b905090565b6109c8610b45565b63389a75e1600c52805f526020600c2080544211156109ee57636f5e88185f526004601cfd5b5f90556109fa81610b5f565b50565b610a05610b45565b8060601b610a1a57637448fbae5f526004601cfd5b6109fa81610b5f565b6005545f03610a455760405163192598ab60e21b815260040160405180910390fd5b5f5b81811015610aa95760055460408051602081019290925281018290527352deaa1c84233f7bb8c8a45baede41091c6165066060820152610aa190608001604051602081830303815290604052805190602001205f1c610b9c565b600101610a47565b506006805482019055600554604080514260208201524391810191909152606081019190915260800160408051601f19818403018152919052805160209091012060055550565b60055415610b115760405163de6897a560e01b815260040160405180910390fd5b600581905560405181907f8fe5325221743b985fbf085f6ffd2bf26e7922ece1a6947b9635d8bca73c760d905f90a2505050565b638b78c6d8195433146105a0576382b429005f526004601cfd5b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a355565b6004545f03610bbe5760405163c072d55d60e01b815260040160405180910390fd5b5f610bc7610d27565b610bf1907f0000000000000000000000000000000000000000000000000000000000000000610f87565b90505f610bfe8284610f9a565b5f81815260016020526040812054919250819003610c195750805b60015f610c268286610f87565b81526020019081526020015f20545f14610c6e5760015f610c478286610f87565b81526020019081526020015f205460015f8481526020019081526020015f20819055610c8a565b610c79600184610f87565b5f8381526001602052604090208190555b50600480545f838152602081815260408083208490559282526002905281812080546fffffffffffffffffffffffffffffffff19811660016001600160801b0392831601821617909155925481522054600160801b81048216911603610cf457600480545f190190555b60045460405182907fc75222c877dfe06d3372771df6b71e1b873abc97c304794d40f3b155feaa9933905f90a350505050565b5f807f00000000000000000000000000000000000000000000000000000000000000005b8015610dad575f81815260026020526040902054610d72906001600160801b031683610f3f565b5f828152600260205260409020549092506001600160801b03600160801b82048116911610610dad5780610da581610fb9565b915050610d4b565b50919050565b67ffffffffffffffff811681146109fa575f5ffd5b5f60208284031215610dd8575f5ffd5b8135610de381610db3565b9392505050565b80356001600160a01b0381168114610e00575f5ffd5b919050565b5f5f5f60608486031215610e17575f5ffd5b8335610e2281610db3565b9250610e3060208501610dea565b9150604084013590509250925092565b5f60208284031215610e50575f5ffd5b5035919050565b5f5f60208385031215610e68575f5ffd5b823567ffffffffffffffff811115610e7e575f5ffd5b8301601f81018513610e8e575f5ffd5b803567ffffffffffffffff811115610ea4575f5ffd5b8560208260051b8401011115610eb8575f5ffd5b6020919091019590945092505050565b5f60208284031215610ed8575f5ffd5b610de382610dea565b6001600160801b03811681146109fa575f5ffd5b5f60208284031215610f05575f5ffd5b8151610de381610ee1565b5f60208284031215610f20575f5ffd5b8151610de381610db3565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610f5257610f52610f2b565b92915050565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215610f7c575f5ffd5b8135610de381610ee1565b81810381811115610f5257610f52610f2b565b5f82610fb457634e487b7160e01b5f52601260045260245ffd5b500690565b5f81610fc757610fc7610f2b565b505f19019056fea2646970667358221220a6b72ed16356e34938ab953e79ff3795ee85fac12fc5b5c8ef4d7472408e457064736f6c634300081c0033000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000003c9
Deployed Bytecode
0x60806040526004361061013c575f3560e01c8063b13038a1116100b3578063f2fde38b1161006d578063f2fde38b1461037d578063f4eff48f14610390578063f5510d62146103af578063f7f73f3e146103e2578063fee81cf41461040d578063fffa65e01461043e575f5ffd5b8063b13038a11461028a578063b5c3dbbb146102ab578063c518435e1461030a578063ccbac9f514610329578063ced72f871461033e578063f04e283e1461036a575f5ffd5b806352a5f1f81161010457806352a5f1f81461020357806354d1f13d14610222578063715018a61461022a5780638a2a9a9d146102325780638da5cb5b1461025d5780639e24410514610275575f5ffd5b8063013c978e14610140578063085d48831461017e57806325692962146101bd578063475d39ff146101c757806347ce07cc146101dc575b5f5ffd5b34801561014b575f5ffd5b5061016b61015a366004610dc8565b60036020525f908152604090205481565b6040519081526020015b60405180910390f35b348015610189575f5ffd5b506101a57352deaa1c84233f7bb8c8a45baede41091c61650681565b6040516001600160a01b039091168152602001610175565b6101c5610471565b005b3480156101d2575f5ffd5b5061016b60065481565b3480156101e7575f5ffd5b506101a57336825bf3fbdf5a29e2d5148bfe7dcf7b5639e32081565b34801561020e575f5ffd5b506101c561021d366004610e05565b6104be565b6101c5610556565b6101c561058f565b34801561023d575f5ffd5b5061016b61024c366004610e40565b5f6020819052908152604090205481565b348015610268575f5ffd5b50638b78c6d819546101a5565b348015610280575f5ffd5b5061016b60045481565b6102926105a2565b60405167ffffffffffffffff9091168152602001610175565b3480156102b6575f5ffd5b506102ea6102c5366004610e40565b60026020525f90815260409020546001600160801b0380821691600160801b90041682565b604080516001600160801b03938416815292909116602083015201610175565b348015610315575f5ffd5b506101c5610324366004610e57565b61073c565b348015610334575f5ffd5b5061016b60055481565b348015610349575f5ffd5b50610352610934565b6040516001600160801b039091168152602001610175565b6101c5610378366004610ec8565b6109c0565b6101c561038b366004610ec8565b6109fd565b34801561039b575f5ffd5b506101c56103aa366004610e40565b610a23565b3480156103ba575f5ffd5b5061016b7f000000000000000000000000000000000000000000000000000000000000000b81565b3480156103ed575f5ffd5b5061016b6103fc366004610e40565b60016020525f908152604090205481565b348015610418575f5ffd5b5061016b610427366004610ec8565b63389a75e1600c9081525f91909152602090205490565b348015610449575f5ffd5b5061016b7f00000000000000000000000000000000000000000000000000000000000003c981565b5f6202a30067ffffffffffffffff164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f5fa250565b7336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3206104e1565b60405180910390fd5b336001600160a01b038216146105455760405162461bcd60e51b815260206004820152602360248201527f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460448201526234b7b760e91b60648201526084016104d8565b610550848484610af0565b50505050565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f5fa2565b610597610b45565b6105a05f610b5f565b565b604051631711922960e31b81527352deaa1c84233f7bb8c8a45baede41091c61650660048201525f9081907336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3209063b88c914890602401602060405180830381865afa158015610607573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061062b9190610ef5565b6040805142602082015243918101919091523360608201529091505f9060800160408051808303601f190181529082905280516020909101206319cb825f60e01b82527352deaa1c84233f7bb8c8a45baede41091c61650660048301526024820181905291505f907336825bf3fbdf5a29e2d5148bfe7dcf7b5639e320906319cb825f906001600160801b0386169060440160206040518083038185885af11580156106d9573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106fe9190610f10565b60405190915067ffffffffffffffff8216907f6ab4d3605438901c2c16d05ecddf4593282d86ff03bc92289aed71ec7ddb37f9905f90a29392505050565b610744610b45565b7f000000000000000000000000000000000000000000000000000000000000000b8114610784576040516307e11acb60e51b815260040160405180910390fd5b5f5f5b828110156108a4575f60028161079e846001610f3f565b815260208101919091526040015f20546001600160801b031611156107d657604051635e241e5160e11b815260040160405180910390fd5b60405180604001604052805f6001600160801b0316815260200185858481811061080257610802610f58565b90506020020160208101906108179190610f6c565b6001600160801b0316905260025f610830846001610f3f565b81526020808201929092526040015f20825192909101516001600160801b03908116600160801b02921691909117905583838281811061087257610872610f58565b90506020020160208101906108879190610f6c565b61089a906001600160801b031683610f3f565b9150600101610787565b507f00000000000000000000000000000000000000000000000000000000000003c981146108e557604051633bb0d26f60e21b815260040160405180910390fd5b6040517f000000000000000000000000000000000000000000000000000000000000000b907fdd39ce343fdf5e27b865f30c5372b4c57b221382dc6bec00a617dc05663814f3905f90a2505050565b604051631711922960e31b81527352deaa1c84233f7bb8c8a45baede41091c61650660048201525f907336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3209063b88c914890602401602060405180830381865afa158015610997573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109bb9190610ef5565b905090565b6109c8610b45565b63389a75e1600c52805f526020600c2080544211156109ee57636f5e88185f526004601cfd5b5f90556109fa81610b5f565b50565b610a05610b45565b8060601b610a1a57637448fbae5f526004601cfd5b6109fa81610b5f565b6005545f03610a455760405163192598ab60e21b815260040160405180910390fd5b5f5b81811015610aa95760055460408051602081019290925281018290527352deaa1c84233f7bb8c8a45baede41091c6165066060820152610aa190608001604051602081830303815290604052805190602001205f1c610b9c565b600101610a47565b506006805482019055600554604080514260208201524391810191909152606081019190915260800160408051601f19818403018152919052805160209091012060055550565b60055415610b115760405163de6897a560e01b815260040160405180910390fd5b600581905560405181907f8fe5325221743b985fbf085f6ffd2bf26e7922ece1a6947b9635d8bca73c760d905f90a2505050565b638b78c6d8195433146105a0576382b429005f526004601cfd5b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a355565b6004545f03610bbe5760405163c072d55d60e01b815260040160405180910390fd5b5f610bc7610d27565b610bf1907f00000000000000000000000000000000000000000000000000000000000003c9610f87565b90505f610bfe8284610f9a565b5f81815260016020526040812054919250819003610c195750805b60015f610c268286610f87565b81526020019081526020015f20545f14610c6e5760015f610c478286610f87565b81526020019081526020015f205460015f8481526020019081526020015f20819055610c8a565b610c79600184610f87565b5f8381526001602052604090208190555b50600480545f838152602081815260408083208490559282526002905281812080546fffffffffffffffffffffffffffffffff19811660016001600160801b0392831601821617909155925481522054600160801b81048216911603610cf457600480545f190190555b60045460405182907fc75222c877dfe06d3372771df6b71e1b873abc97c304794d40f3b155feaa9933905f90a350505050565b5f807f000000000000000000000000000000000000000000000000000000000000000b5b8015610dad575f81815260026020526040902054610d72906001600160801b031683610f3f565b5f828152600260205260409020549092506001600160801b03600160801b82048116911610610dad5780610da581610fb9565b915050610d4b565b50919050565b67ffffffffffffffff811681146109fa575f5ffd5b5f60208284031215610dd8575f5ffd5b8135610de381610db3565b9392505050565b80356001600160a01b0381168114610e00575f5ffd5b919050565b5f5f5f60608486031215610e17575f5ffd5b8335610e2281610db3565b9250610e3060208501610dea565b9150604084013590509250925092565b5f60208284031215610e50575f5ffd5b5035919050565b5f5f60208385031215610e68575f5ffd5b823567ffffffffffffffff811115610e7e575f5ffd5b8301601f81018513610e8e575f5ffd5b803567ffffffffffffffff811115610ea4575f5ffd5b8560208260051b8401011115610eb8575f5ffd5b6020919091019590945092505050565b5f60208284031215610ed8575f5ffd5b610de382610dea565b6001600160801b03811681146109fa575f5ffd5b5f60208284031215610f05575f5ffd5b8151610de381610ee1565b5f60208284031215610f20575f5ffd5b8151610de381610db3565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610f5257610f52610f2b565b92915050565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215610f7c575f5ffd5b8135610de381610ee1565b81810381811115610f5257610f52610f2b565b5f82610fb457634e487b7160e01b5f52601260045260245ffd5b500690565b5f81610fc757610fc7610f2b565b505f19019056fea2646970667358221220a6b72ed16356e34938ab953e79ff3795ee85fac12fc5b5c8ef4d7472408e457064736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000003c9
-----Decoded View---------------
Arg [0] : _numberOfTiers (uint256): 11
Arg [1] : _maxSupply (uint256): 969
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000000000000000000000000000000000b
Arg [1] : 00000000000000000000000000000000000000000000000000000000000003c9
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.