More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 242 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 9636986 | 3 hrs ago | IN | 1 APE | 0.00141763 | ||||
Transfer | 9633195 | 4 hrs ago | IN | 10 APE | 0.00141763 | ||||
Transfer | 9506717 | 2 days ago | IN | 1 APE | 0.00141763 | ||||
Transfer | 9488256 | 2 days ago | IN | 1 APE | 0.00141763 | ||||
Transfer | 9487343 | 2 days ago | IN | 69 APE | 0.00141761 | ||||
Transfer | 9485144 | 2 days ago | IN | 1 APE | 0.00141763 | ||||
Transfer | 9477780 | 2 days ago | IN | 1 APE | 0.00141763 | ||||
Transfer | 9475722 | 3 days ago | IN | 20 APE | 0.00141761 | ||||
Transfer | 9475188 | 3 days ago | IN | 11 APE | 0.00141761 | ||||
Transfer | 9474651 | 3 days ago | IN | 1 APE | 0.00141761 | ||||
Transfer | 9474299 | 3 days ago | IN | 32 APE | 0.00141763 | ||||
Transfer | 9474169 | 3 days ago | IN | 3 APE | 0.00141761 | ||||
Transfer | 9473076 | 3 days ago | IN | 10 APE | 0.00141761 | ||||
Transfer | 9472704 | 3 days ago | IN | 1 APE | 0.00141763 | ||||
Transfer | 9471886 | 3 days ago | IN | 10 APE | 0.00141761 | ||||
Transfer | 9470961 | 3 days ago | IN | 3 APE | 0.00141761 | ||||
Transfer | 9470763 | 3 days ago | IN | 1 APE | 0.00141763 | ||||
Transfer | 9470537 | 3 days ago | IN | 10 APE | 0.00141763 | ||||
Transfer | 9470533 | 3 days ago | IN | 3 APE | 0.00141763 | ||||
Transfer | 9470518 | 3 days ago | IN | 10 APE | 0.00141763 | ||||
Transfer | 9470063 | 3 days ago | IN | 1 APE | 0.00141763 | ||||
Transfer | 9470039 | 3 days ago | IN | 1 APE | 0.00141763 | ||||
Transfer | 9469678 | 3 days ago | IN | 10 APE | 0.00141763 | ||||
Transfer | 9469576 | 3 days ago | IN | 30 APE | 0.00141761 | ||||
Transfer | 9469537 | 3 days ago | IN | 10 APE | 0.00141761 |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ApeBomb
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"; interface INFTShadow { function ownerOf(uint256 tokenId) external view returns (address); } interface INFTWinnerClaim { function setWinner(uint256 tournamentId, address contractAddress, uint256 tokenId) external payable; } interface IERC20 { function balanceOf(address account) external view returns (uint256); function transfer(address to, uint256 amount) external returns (bool); } struct NftContract { address contractAddress; uint32 startTokenId; uint32 endTokenId; } struct Tournament { uint256 nextEntryToAssign; mapping(uint256 explicitEntry => address entrant) explicitEntries; } contract ApeBomb is IEntropyConsumer, Ownable { error InvalidAmount(); error TransferFailed(); error TargetExceeded(); error EmergencyWithdrawNotYetRequested(); error EmergencyWithdrawNotYetAvailable(); error InvalidTokenAddress(); event Entered( uint256 indexed tournamentId, address indexed entrant, uint256 startEntryNumber, uint256 endEntryNumber ); event WinnerSelected(uint256 indexed tournamentId, address indexed winner, uint256 amount); event NftWinnerSelected(uint256 indexed tournamentId, address indexed contractAddress, uint256 tokenId); event ClaimContractSet(address indexed claimContract); event NftContractSet(address indexed nftContract, uint32 startTokenId, uint32 endTokenId); event EmergencyWithdrawRequested(uint256 emergencyWithdrawTimestamp); IEntropy public constant entropy = IEntropy(0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320); address public constant provider = 0x52DeaA1c84233F7bb8C8A45baeDE41091c616506; mapping(uint256 tournamentId => Tournament tournament) public tournaments; address public nftWinnerClaimContract; uint256 public currentTournamentId; uint256 public emergencyWithdrawTimestamp; NftContract public currentNftContract; uint256 private constant _WINNER_SELECTION_THRESHOLD = 100_000 ether; uint256 private constant _TOTAL_ENTRIES = 1_000_000; uint256 private constant _TARGET_ENTRIES = 999_000; constructor() { _initializeOwner(msg.sender); } // Automatically place bet when receiving ETH receive() external payable { if (msg.sender != nftWinnerClaimContract) { _enter(); } } function setNftWinnerClaimContract(address _nftWinnerClaimContract) external onlyOwner { nftWinnerClaimContract = _nftWinnerClaimContract; emit ClaimContractSet(_nftWinnerClaimContract); } function setNftContract(NftContract memory nftContract) external onlyOwner { currentNftContract = nftContract; emit NftContractSet(nftContract.contractAddress, nftContract.startTokenId, nftContract.endTokenId); } /** * @dev emergency withdraw function in case Pyth ceases to function * @notice 1 year wait period before withdraw can be fulfilled, to prevent malicious withdrawals * @notice if tournament turns over during the 1 year wait period, the withdraw request will be reset */ function requestEmergencyWithdraw() external onlyOwner { emergencyWithdrawTimestamp = block.timestamp + 365 days; emit EmergencyWithdrawRequested(emergencyWithdrawTimestamp); } function fulfillEmergencyWithdraw() external onlyOwner { if (emergencyWithdrawTimestamp == 0) revert EmergencyWithdrawNotYetRequested(); if (block.timestamp < emergencyWithdrawTimestamp) revert EmergencyWithdrawNotYetAvailable(); (bool success,) = msg.sender.call{value: address(this).balance}(""); if (!success) revert TransferFailed(); } function rescueERC20(address tokenAddress, address to) external onlyOwner { if (tokenAddress == address(0)) revert InvalidTokenAddress(); uint256 balance = IERC20(tokenAddress).balanceOf(address(this)); IERC20(tokenAddress).transfer(to, balance); } function entropyCallback(uint64, /* sequenceNumber */ address, /* provider */ bytes32 randomNumber) internal override { if (address(this).balance < _WINNER_SELECTION_THRESHOLD) return; uint256 random = uint256(randomNumber); uint256 entryNumber = random % _TOTAL_ENTRIES; address currentNftContractAddress = currentNftContract.contractAddress; bool isNftWinner = entryNumber > _TARGET_ENTRIES && currentNftContractAddress != address(0); if (isNftWinner) { // generate a random tokenId between startTokenId and endTokenId uint256 tokenId = (random % (currentNftContract.endTokenId - currentNftContract.startTokenId + 1)) + currentNftContract.startTokenId; // enforce token exists with a try/catch ownerOf call try INFTShadow(currentNftContractAddress).ownerOf(tokenId) returns (address) { INFTWinnerClaim(nftWinnerClaimContract).setWinner{value: address(this).balance}( currentTournamentId, currentNftContractAddress, tokenId ); emit NftWinnerSelected(currentTournamentId, currentNftContractAddress, tokenId); } catch { return; } } else { // check if entry number is in the tournament if (entryNumber >= tournaments[currentTournamentId].nextEntryToAssign) return; address entrant = _findEntrant(entryNumber); if (entrant == address(0)) return; // transfer to winner (bool success,) = entrant.call{value: address(this).balance}(""); if (!success) revert TransferFailed(); emit WinnerSelected(currentTournamentId, entrant, address(this).balance); } emergencyWithdrawTimestamp = 0; unchecked { ++currentTournamentId; } } function _enter() internal { // Validate bet amount is divisible by 1 ether if (msg.value == 0 || msg.value % 1 ether != 0 || msg.value > 1_000 ether) revert InvalidAmount(); uint256 numEntries = msg.value / 1 ether; _assignEntrant(numEntries); // pay the fees and request a random number from entropy if more than 100_000 entries if (address(this).balance > _WINNER_SELECTION_THRESHOLD) { bytes32 pseudoRandomNumber = keccak256(abi.encode(block.timestamp, block.number, msg.sender, address(this).balance)); // get the required fee uint128 requestFee = entropy.getFee(provider); entropy.requestWithCallback{value: requestFee}(provider, pseudoRandomNumber); } } // This method is required by the IEntropyConsumer interface function getEntropy() internal pure override returns (address) { return address(entropy); } function _assignEntrant(uint256 numEntries) internal { // set at least 1 explicit entry per 100 total entries to get _findEntrant under 500k gas max uint256 entryNumber = tournaments[currentTournamentId].nextEntryToAssign; uint256 totalExplicitEntriesToSet = numEntries / 100 + 1; for (uint256 i = 0; i < totalExplicitEntriesToSet; ++i) { uint256 explicitEntryNumber; unchecked { explicitEntryNumber = entryNumber + i * 100; } tournaments[currentTournamentId].explicitEntries[explicitEntryNumber] = msg.sender; } uint256 nextEntryToAssign; unchecked { nextEntryToAssign = entryNumber + numEntries; } if (nextEntryToAssign > _TARGET_ENTRIES) revert TargetExceeded(); tournaments[currentTournamentId].nextEntryToAssign = nextEntryToAssign; emit Entered(currentTournamentId, msg.sender, entryNumber, nextEntryToAssign - 1); } function _findEntrant(uint256 entryNumber) internal view returns (address) { for (uint256 i = entryNumber; i >= 0; --i) { address entrant = tournaments[currentTournamentId].explicitEntries[i]; if (entrant != address(0)) { return entrant; } if (i == 0) { return address(0); } } return address(0); } }
// 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": [ "@pythnetwork/entropy-sdk-solidity/=node_modules/@pythnetwork/entropy-sdk-solidity/", "solady/=lib/solady/src/", "forge-std/=lib/forge-std/src/" ], "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":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"EmergencyWithdrawNotYetAvailable","type":"error"},{"inputs":[],"name":"EmergencyWithdrawNotYetRequested","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidTokenAddress","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"TargetExceeded","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimContract","type":"address"}],"name":"ClaimContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"emergencyWithdrawTimestamp","type":"uint256"}],"name":"EmergencyWithdrawRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tournamentId","type":"uint256"},{"indexed":true,"internalType":"address","name":"entrant","type":"address"},{"indexed":false,"internalType":"uint256","name":"startEntryNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endEntryNumber","type":"uint256"}],"name":"Entered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nftContract","type":"address"},{"indexed":false,"internalType":"uint32","name":"startTokenId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"endTokenId","type":"uint32"}],"name":"NftContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tournamentId","type":"uint256"},{"indexed":true,"internalType":"address","name":"contractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NftWinnerSelected","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":"uint256","name":"tournamentId","type":"uint256"},{"indexed":true,"internalType":"address","name":"winner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WinnerSelected","type":"event"},{"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":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"currentNftContract","outputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint32","name":"startTokenId","type":"uint32"},{"internalType":"uint32","name":"endTokenId","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentTournamentId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencyWithdrawTimestamp","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":[],"name":"fulfillEmergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nftWinnerClaimContract","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestEmergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"rescueERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint32","name":"startTokenId","type":"uint32"},{"internalType":"uint32","name":"endTokenId","type":"uint32"}],"internalType":"struct NftContract","name":"nftContract","type":"tuple"}],"name":"setNftContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftWinnerClaimContract","type":"address"}],"name":"setNftWinnerClaimContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tournamentId","type":"uint256"}],"name":"tournaments","outputs":[{"internalType":"uint256","name":"nextEntryToAssign","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6080604052348015600e575f5ffd5b50601633601a565b6055565b6001600160a01b0316638b78c6d819819055805f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b6111ab806100625f395ff3fe60806040526004361061011e575f3560e01c80637503e1b71161009d578063e36a6d4d11610062578063e36a6d4d14610334578063f04e283e14610353578063f2fde38b14610366578063fc8e750414610379578063fee81cf41461038e575f5ffd5b80637503e1b71461029f578063756f80d0146102ca5780638836c7c7146102e95780638da5cb5b14610308578063c28f7c3b14610320575f5ffd5b806347ce07cc116100e357806347ce07cc1461022a57806352a5f1f81461025157806354d1f13d146102705780635d799f8714610278578063715018a614610297575f5ffd5b8063085d48831461014357806323383e8a1461018757806325692962146101aa5780633a4d29a0146101b25780633bab39c914610216575f5ffd5b3661013f576001546001600160a01b0316331461013d5761013d6103bf565b005b5f5ffd5b34801561014e575f5ffd5b5061016a7352deaa1c84233f7bb8c8a45baede41091c61650681565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610192575f5ffd5b5061019c60035481565b60405190815260200161017e565b61013d6105a2565b3480156101bd575f5ffd5b506004546101ea906001600160a01b0381169063ffffffff600160a01b8204811691600160c01b90041683565b604080516001600160a01b03909416845263ffffffff928316602085015291169082015260600161017e565b348015610221575f5ffd5b5061013d6105ef565b348015610235575f5ffd5b5061016a7336825bf3fbdf5a29e2d5148bfe7dcf7b5639e32081565b34801561025c575f5ffd5b5061013d61026b366004610edc565b6106a2565b61013d610734565b348015610283575f5ffd5b5061013d610292366004610f1a565b61076d565b61013d610878565b3480156102aa575f5ffd5b5061019c6102b9366004610f51565b5f6020819052908152604090205481565b3480156102d5575f5ffd5b5060015461016a906001600160a01b031681565b3480156102f4575f5ffd5b5061013d610303366004610f68565b61088b565b348015610313575f5ffd5b50638b78c6d8195461016a565b34801561032b575f5ffd5b5061013d6108dc565b34801561033f575f5ffd5b5061013d61034e366004610fa2565b61092c565b61013d610361366004610f68565b6109c8565b61013d610374366004610f68565b610a02565b348015610384575f5ffd5b5061019c60025481565b348015610399575f5ffd5b5061019c6103a8366004610f68565b63389a75e1600c9081525f91909152602090205490565b3415806103dc57506103d9670de0b6b3a764000034611030565b15155b806103ef5750683635c9adc5dea0000034115b1561040d5760405163162908e360e11b815260040160405180910390fd5b5f610420670de0b6b3a764000034611057565b905061042b81610a28565b69152d02c7e14af680000047111561059f576040805142602082015243918101919091523360608201524760808201525f9060a00160408051808303601f19018152908290528051602090910120631711922960e31b82527352deaa1c84233f7bb8c8a45baede41091c616506600483015291505f907336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3209063b88c914890602401602060405180830381865afa1580156104db573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ff919061106a565b6040516319cb825f60e01b81527352deaa1c84233f7bb8c8a45baede41091c6165066004820152602481018490529091507336825bf3fbdf5a29e2d5148bfe7dcf7b5639e320906319cb825f906001600160801b0384169060440160206040518083038185885af1158015610576573d5f5f3e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061059b9190611090565b5050505b50565b5f6202a30067ffffffffffffffff164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f5fa250565b6105f7610b20565b6003545f036106195760405163702e107b60e11b815260040160405180910390fd5b60035442101561063c5760405163312df54960e21b815260040160405180910390fd5b6040515f90339047908381818185875af1925050503d805f811461067b576040519150601f19603f3d011682016040523d82523d5f602084013e610680565b606091505b505090508061059f576040516312171d8360e31b815260040160405180910390fd5b7336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3206106c5565b60405180910390fd5b336001600160a01b038216146107295760405162461bcd60e51b815260206004820152602360248201527f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460448201526234b7b760e91b60648201526084016106bc565b61059b848484610b3a565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f5fa2565b610775610b20565b6001600160a01b03821661079c57604051630f58058360e11b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa1580156107e0573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080491906110ab565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018390529192509084169063a9059cbb906044016020604051808303815f875af1158015610854573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061059b91906110c2565b610880610b20565b6108895f610e1f565b565b610893610b20565b600180546001600160a01b0319166001600160a01b0383169081179091556040517fbf77f8a166e9bdd137896351a3fea0853166f5ad052c99f89c0e300c5d4f2137905f90a250565b6108e4610b20565b6108f2426301e133806110e1565b60038190556040519081527f6c51e0e9648746b65a27425fd08714243ff8799934a67ee370cde94eb5e415039060200160405180910390a1565b610934610b20565b8051600480546020808501516040808701516001600160a01b039096166001600160c01b03199094168417600160a01b63ffffffff9384169081029190911763ffffffff60c01b1916600160c01b9390971692830296909617909455835194855290840152917f57e89783ddc2d134e6bead9466d567175a69a79ba594c8688f3d9d5b52909a92910160405180910390a250565b6109d0610b20565b63389a75e1600c52805f526020600c2080544211156109f657636f5e88185f526004601cfd5b5f905561059f81610e1f565b610a0a610b20565b8060601b610a1f57637448fbae5f526004601cfd5b61059f81610e1f565b6002545f9081526020819052604081205490610a45606484611057565b610a509060016110e1565b90505f5b81811015610a96576002545f908152602081815260408083206064850287018452600190810190925290912080546001600160a01b0319163317905501610a54565b50818301620f3e58811115610abe57604051636d7a147360e01b815260040160405180910390fd5b600280545f9081526020819052604090208290555433907f67f18c62d694f27ab65863682a2757fc3881081d5274f7fe7deb533a5ef32b9e85610b026001866110fa565b6040805192835260208301919091520160405180910390a350505050565b638b78c6d819543314610889576382b429005f526004601cfd5b69152d02c7e14af6800000471015610b5157505050565b805f610b60620f424083611030565b6004549091506001600160a01b03165f620f3e5883118015610b8a57506001600160a01b03821615155b90508015610d0c576004545f9063ffffffff600160a01b8204811691610bb9918391600160c01b90041661110d565b610bc4906001611129565b610bd49063ffffffff1687611030565b610bde91906110e1565b6040516331a9108f60e11b8152600481018290529091506001600160a01b03841690636352211e90602401602060405180830381865afa925050508015610c42575060408051601f3d908101601f19168201909252610c3f91810190611145565b60015b610c50575050505050505050565b6001546002546040516351b4228360e01b815260048101919091526001600160a01b03868116602483015260448201859052909116906351b422839047906064015f604051808303818588803b158015610ca8575f5ffd5b505af1158015610cba573d5f5f3e3d5ffd5b5050505050836001600160a01b03166002547fc1799ee088079468982fc52207857c70548b2d9f51ec5a88f0d8a1b29785a56284604051610cfd91815260200190565b60405180910390a35050610e09565b6002545f908152602081905260409020548310610d2c5750505050505050565b5f610d3684610e5c565b90506001600160a01b038116610d50575050505050505050565b5f816001600160a01b0316476040515f6040518083038185875af1925050503d805f8114610d99576040519150601f19603f3d011682016040523d82523d5f602084013e610d9e565b606091505b5050905080610dc0576040516312171d8360e31b815260040160405180910390fd5b816001600160a01b03166002547ffee5b04775e1cd2311ed22cd00f5d2403aff38ff6f71d6d393f51854ed6bc98647604051610dfe91815260200190565b60405180910390a350505b50505f6003555050600280546001019055505050565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a355565b5f815b6002545f908152602081815260408083208484526001019091529020546001600160a01b03168015610e92579392505050565b815f03610ea257505f9392505050565b50610eac81611160565b9050610e5f565b67ffffffffffffffff8116811461059f575f5ffd5b6001600160a01b038116811461059f575f5ffd5b5f5f5f60608486031215610eee575f5ffd5b8335610ef981610eb3565b92506020840135610f0981610ec8565b929592945050506040919091013590565b5f5f60408385031215610f2b575f5ffd5b8235610f3681610ec8565b91506020830135610f4681610ec8565b809150509250929050565b5f60208284031215610f61575f5ffd5b5035919050565b5f60208284031215610f78575f5ffd5b8135610f8381610ec8565b9392505050565b803563ffffffff81168114610f9d575f5ffd5b919050565b5f6060828403128015610fb3575f5ffd5b506040516060810167ffffffffffffffff81118282101715610fe357634e487b7160e01b5f52604160045260245ffd5b6040528235610ff181610ec8565b8152610fff60208401610f8a565b602082015261101060408401610f8a565b60408201529392505050565b634e487b7160e01b5f52601260045260245ffd5b5f8261103e5761103e61101c565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f826110655761106561101c565b500490565b5f6020828403121561107a575f5ffd5b81516001600160801b0381168114610f83575f5ffd5b5f602082840312156110a0575f5ffd5b8151610f8381610eb3565b5f602082840312156110bb575f5ffd5b5051919050565b5f602082840312156110d2575f5ffd5b81518015158114610f83575f5ffd5b808201808211156110f4576110f4611043565b92915050565b818103818111156110f4576110f4611043565b63ffffffff82811682821603908111156110f4576110f4611043565b63ffffffff81811683821601908111156110f4576110f4611043565b5f60208284031215611155575f5ffd5b8151610f8381610ec8565b5f8161116e5761116e611043565b505f19019056fea264697066735822122037403e7b0519f185eb8000278ce1a5ef73236d4c08eb77f663167877478c2d4464736f6c634300081c0033
Deployed Bytecode
0x60806040526004361061011e575f3560e01c80637503e1b71161009d578063e36a6d4d11610062578063e36a6d4d14610334578063f04e283e14610353578063f2fde38b14610366578063fc8e750414610379578063fee81cf41461038e575f5ffd5b80637503e1b71461029f578063756f80d0146102ca5780638836c7c7146102e95780638da5cb5b14610308578063c28f7c3b14610320575f5ffd5b806347ce07cc116100e357806347ce07cc1461022a57806352a5f1f81461025157806354d1f13d146102705780635d799f8714610278578063715018a614610297575f5ffd5b8063085d48831461014357806323383e8a1461018757806325692962146101aa5780633a4d29a0146101b25780633bab39c914610216575f5ffd5b3661013f576001546001600160a01b0316331461013d5761013d6103bf565b005b5f5ffd5b34801561014e575f5ffd5b5061016a7352deaa1c84233f7bb8c8a45baede41091c61650681565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610192575f5ffd5b5061019c60035481565b60405190815260200161017e565b61013d6105a2565b3480156101bd575f5ffd5b506004546101ea906001600160a01b0381169063ffffffff600160a01b8204811691600160c01b90041683565b604080516001600160a01b03909416845263ffffffff928316602085015291169082015260600161017e565b348015610221575f5ffd5b5061013d6105ef565b348015610235575f5ffd5b5061016a7336825bf3fbdf5a29e2d5148bfe7dcf7b5639e32081565b34801561025c575f5ffd5b5061013d61026b366004610edc565b6106a2565b61013d610734565b348015610283575f5ffd5b5061013d610292366004610f1a565b61076d565b61013d610878565b3480156102aa575f5ffd5b5061019c6102b9366004610f51565b5f6020819052908152604090205481565b3480156102d5575f5ffd5b5060015461016a906001600160a01b031681565b3480156102f4575f5ffd5b5061013d610303366004610f68565b61088b565b348015610313575f5ffd5b50638b78c6d8195461016a565b34801561032b575f5ffd5b5061013d6108dc565b34801561033f575f5ffd5b5061013d61034e366004610fa2565b61092c565b61013d610361366004610f68565b6109c8565b61013d610374366004610f68565b610a02565b348015610384575f5ffd5b5061019c60025481565b348015610399575f5ffd5b5061019c6103a8366004610f68565b63389a75e1600c9081525f91909152602090205490565b3415806103dc57506103d9670de0b6b3a764000034611030565b15155b806103ef5750683635c9adc5dea0000034115b1561040d5760405163162908e360e11b815260040160405180910390fd5b5f610420670de0b6b3a764000034611057565b905061042b81610a28565b69152d02c7e14af680000047111561059f576040805142602082015243918101919091523360608201524760808201525f9060a00160408051808303601f19018152908290528051602090910120631711922960e31b82527352deaa1c84233f7bb8c8a45baede41091c616506600483015291505f907336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3209063b88c914890602401602060405180830381865afa1580156104db573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ff919061106a565b6040516319cb825f60e01b81527352deaa1c84233f7bb8c8a45baede41091c6165066004820152602481018490529091507336825bf3fbdf5a29e2d5148bfe7dcf7b5639e320906319cb825f906001600160801b0384169060440160206040518083038185885af1158015610576573d5f5f3e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061059b9190611090565b5050505b50565b5f6202a30067ffffffffffffffff164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f5fa250565b6105f7610b20565b6003545f036106195760405163702e107b60e11b815260040160405180910390fd5b60035442101561063c5760405163312df54960e21b815260040160405180910390fd5b6040515f90339047908381818185875af1925050503d805f811461067b576040519150601f19603f3d011682016040523d82523d5f602084013e610680565b606091505b505090508061059f576040516312171d8360e31b815260040160405180910390fd5b7336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3206106c5565b60405180910390fd5b336001600160a01b038216146107295760405162461bcd60e51b815260206004820152602360248201527f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460448201526234b7b760e91b60648201526084016106bc565b61059b848484610b3a565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f5fa2565b610775610b20565b6001600160a01b03821661079c57604051630f58058360e11b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa1580156107e0573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080491906110ab565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018390529192509084169063a9059cbb906044016020604051808303815f875af1158015610854573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061059b91906110c2565b610880610b20565b6108895f610e1f565b565b610893610b20565b600180546001600160a01b0319166001600160a01b0383169081179091556040517fbf77f8a166e9bdd137896351a3fea0853166f5ad052c99f89c0e300c5d4f2137905f90a250565b6108e4610b20565b6108f2426301e133806110e1565b60038190556040519081527f6c51e0e9648746b65a27425fd08714243ff8799934a67ee370cde94eb5e415039060200160405180910390a1565b610934610b20565b8051600480546020808501516040808701516001600160a01b039096166001600160c01b03199094168417600160a01b63ffffffff9384169081029190911763ffffffff60c01b1916600160c01b9390971692830296909617909455835194855290840152917f57e89783ddc2d134e6bead9466d567175a69a79ba594c8688f3d9d5b52909a92910160405180910390a250565b6109d0610b20565b63389a75e1600c52805f526020600c2080544211156109f657636f5e88185f526004601cfd5b5f905561059f81610e1f565b610a0a610b20565b8060601b610a1f57637448fbae5f526004601cfd5b61059f81610e1f565b6002545f9081526020819052604081205490610a45606484611057565b610a509060016110e1565b90505f5b81811015610a96576002545f908152602081815260408083206064850287018452600190810190925290912080546001600160a01b0319163317905501610a54565b50818301620f3e58811115610abe57604051636d7a147360e01b815260040160405180910390fd5b600280545f9081526020819052604090208290555433907f67f18c62d694f27ab65863682a2757fc3881081d5274f7fe7deb533a5ef32b9e85610b026001866110fa565b6040805192835260208301919091520160405180910390a350505050565b638b78c6d819543314610889576382b429005f526004601cfd5b69152d02c7e14af6800000471015610b5157505050565b805f610b60620f424083611030565b6004549091506001600160a01b03165f620f3e5883118015610b8a57506001600160a01b03821615155b90508015610d0c576004545f9063ffffffff600160a01b8204811691610bb9918391600160c01b90041661110d565b610bc4906001611129565b610bd49063ffffffff1687611030565b610bde91906110e1565b6040516331a9108f60e11b8152600481018290529091506001600160a01b03841690636352211e90602401602060405180830381865afa925050508015610c42575060408051601f3d908101601f19168201909252610c3f91810190611145565b60015b610c50575050505050505050565b6001546002546040516351b4228360e01b815260048101919091526001600160a01b03868116602483015260448201859052909116906351b422839047906064015f604051808303818588803b158015610ca8575f5ffd5b505af1158015610cba573d5f5f3e3d5ffd5b5050505050836001600160a01b03166002547fc1799ee088079468982fc52207857c70548b2d9f51ec5a88f0d8a1b29785a56284604051610cfd91815260200190565b60405180910390a35050610e09565b6002545f908152602081905260409020548310610d2c5750505050505050565b5f610d3684610e5c565b90506001600160a01b038116610d50575050505050505050565b5f816001600160a01b0316476040515f6040518083038185875af1925050503d805f8114610d99576040519150601f19603f3d011682016040523d82523d5f602084013e610d9e565b606091505b5050905080610dc0576040516312171d8360e31b815260040160405180910390fd5b816001600160a01b03166002547ffee5b04775e1cd2311ed22cd00f5d2403aff38ff6f71d6d393f51854ed6bc98647604051610dfe91815260200190565b60405180910390a350505b50505f6003555050600280546001019055505050565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a355565b5f815b6002545f908152602081815260408083208484526001019091529020546001600160a01b03168015610e92579392505050565b815f03610ea257505f9392505050565b50610eac81611160565b9050610e5f565b67ffffffffffffffff8116811461059f575f5ffd5b6001600160a01b038116811461059f575f5ffd5b5f5f5f60608486031215610eee575f5ffd5b8335610ef981610eb3565b92506020840135610f0981610ec8565b929592945050506040919091013590565b5f5f60408385031215610f2b575f5ffd5b8235610f3681610ec8565b91506020830135610f4681610ec8565b809150509250929050565b5f60208284031215610f61575f5ffd5b5035919050565b5f60208284031215610f78575f5ffd5b8135610f8381610ec8565b9392505050565b803563ffffffff81168114610f9d575f5ffd5b919050565b5f6060828403128015610fb3575f5ffd5b506040516060810167ffffffffffffffff81118282101715610fe357634e487b7160e01b5f52604160045260245ffd5b6040528235610ff181610ec8565b8152610fff60208401610f8a565b602082015261101060408401610f8a565b60408201529392505050565b634e487b7160e01b5f52601260045260245ffd5b5f8261103e5761103e61101c565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f826110655761106561101c565b500490565b5f6020828403121561107a575f5ffd5b81516001600160801b0381168114610f83575f5ffd5b5f602082840312156110a0575f5ffd5b8151610f8381610eb3565b5f602082840312156110bb575f5ffd5b5051919050565b5f602082840312156110d2575f5ffd5b81518015158114610f83575f5ffd5b808201808211156110f4576110f4611043565b92915050565b818103818111156110f4576110f4611043565b63ffffffff82811682821603908111156110f4576110f4611043565b63ffffffff81811683821601908111156110f4576110f4611043565b5f60208284031215611155575f5ffd5b8151610f8381610ec8565b5f8161116e5761116e611043565b505f19019056fea264697066735822122037403e7b0519f185eb8000278ce1a5ef73236d4c08eb77f663167877478c2d4464736f6c634300081c0033
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.