Overview
APE Balance
APE Value
$61.01 (@ $0.69/APE)More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 179 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 10404388 | 2 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10393737 | 7 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10393472 | 7 hrs ago | IN | 2 APE | 0.0031954 | ||||
Transfer | 10386448 | 9 hrs ago | IN | 2 APE | 0.00319538 | ||||
Transfer | 10386345 | 9 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10383159 | 10 hrs ago | IN | 1 APE | 0.00319538 | ||||
Transfer | 10381625 | 11 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10374508 | 13 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10374391 | 13 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10374324 | 13 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10373739 | 14 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10369875 | 16 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10369718 | 16 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10336041 | 33 hrs ago | IN | 2 APE | 0.0031954 | ||||
Transfer | 10324174 | 38 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10317509 | 42 hrs ago | IN | 11 APE | 0.0031954 | ||||
Transfer | 10316683 | 43 hrs ago | IN | 1 APE | 0.00319538 | ||||
Transfer | 10312410 | 45 hrs ago | IN | 40 APE | 0.0031954 | ||||
Transfer | 10307430 | 47 hrs ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10305672 | 2 days ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10305423 | 2 days ago | IN | 3 APE | 0.0031954 | ||||
Transfer | 10304691 | 2 days ago | IN | 1 APE | 0.00319538 | ||||
Transfer | 10304286 | 2 days ago | IN | 1 APE | 0.0031954 | ||||
Transfer | 10303816 | 2 days ago | IN | 1 APE | 0.00319538 | ||||
Transfer | 10303008 | 2 days ago | IN | 1 APE | 0.00319538 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
10404388 | 2 hrs ago | 0.01830289 APE | ||||
10393737 | 7 hrs ago | 0.01830289 APE | ||||
10393472 | 7 hrs ago | 0.01830289 APE | ||||
10386448 | 9 hrs ago | 0.01830289 APE | ||||
10386345 | 9 hrs ago | 0.01830289 APE | ||||
10383159 | 10 hrs ago | 0.01830289 APE | ||||
10381625 | 11 hrs ago | 0.01830289 APE | ||||
10374508 | 13 hrs ago | 0.01830289 APE | ||||
10374391 | 13 hrs ago | 0.01830289 APE | ||||
10374324 | 13 hrs ago | 0.01830289 APE | ||||
10373739 | 14 hrs ago | 0.01830289 APE | ||||
10369875 | 16 hrs ago | 0.01830289 APE | ||||
10369718 | 16 hrs ago | 0.01830289 APE | ||||
10336041 | 33 hrs ago | 0.01830289 APE | ||||
10324174 | 38 hrs ago | 0.01830289 APE | ||||
10317509 | 42 hrs ago | 0.01830289 APE | ||||
10316683 | 43 hrs ago | 0.01830289 APE | ||||
10312410 | 45 hrs ago | 0.01830289 APE | ||||
10307430 | 47 hrs ago | 0.01830289 APE | ||||
10305672 | 2 days ago | 0.01830289 APE | ||||
10305423 | 2 days ago | 0.01830289 APE | ||||
10304691 | 2 days ago | 0.01830289 APE | ||||
10304286 | 2 days ago | 0.01830289 APE | ||||
10303816 | 2 days ago | 0.01830289 APE | ||||
10303008 | 2 days ago | 0.01830289 APE |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ApePinata
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 ArbInfo { function configureDelegateYield(address delegate) external; } 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 ApePinata is IEntropyConsumer, Ownable { error InvalidAmount(); error TransferFailed(); error TargetExceeded(); error InvalidTokenAddress(); error EmergencyWithdrawNotYetRequested(); error EmergencyWithdrawNotYetAvailable(); error InvalidSender(); event Entered( uint256 indexed tournamentId, address indexed entrant, uint256 startEntryNumber, uint256 endEntryNumber ); event WinnerSelected(uint256 indexed tournamentId, address indexed winner, uint256 amount); event EmergencyWithdrawRequested(uint256 emergencyWithdrawTimestamp); IEntropy public constant entropy = IEntropy(0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320); address public constant provider = 0x52DeaA1c84233F7bb8C8A45baeDE41091c616506; address public constant arbInfo = 0x0000000000000000000000000000000000000065; address public constant apeBomb = 0xC1932844eDcc3193ae2622089c4B57ae5F023D7f; mapping(uint256 tournamentId => Tournament tournament) public tournaments; uint256 public currentTournamentId; uint256 public emergencyWithdrawTimestamp; NftContract public currentNftContract; uint256 public currentTarget = 100; uint256 public remainingToSend = 0; constructor() { _initializeOwner(msg.sender); } // Automatically place bet when receiving ETH receive() external payable { if (msg.sender == apeBomb) { // cannot win the ApeBomb prize revert InvalidSender(); } if (remainingToSend > 0) { if (remainingToSend > 1000 ether) { (bool success,) = apeBomb.call{value: 1000 ether}(""); if (!success) revert TransferFailed(); unchecked { remainingToSend -= 1000 ether; } } else { (bool success,) = apeBomb.call{value: remainingToSend}(""); if (!success) revert TransferFailed(); remainingToSend = 0; } } else { _enter(); } } /** * @dev emergency withdraw function in case Pyth ceases to function * @notice 30 day wait period before withdraw can be fulfilled, to prevent malicious withdrawals * @notice if tournament turns over during the 30 day 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 { uint256 random = uint256(randomNumber); uint256 entryNumber = random % currentTarget; // check if entry number is in the tournament if (entryNumber >= tournaments[currentTournamentId].nextEntryToAssign) return; address entrant = _findEntrant(entryNumber); if (entrant == address(0)) return; // set aside 2% for ApeBomb, rounded down to the nearest ether uint256 twoPercent = address(this).balance / 100 ether * 2 ether; (bool success,) = entrant.call{value: address(this).balance - twoPercent}(""); if (!success) revert TransferFailed(); // transfer the rest (2%) to ApeBomb, if > 1000 ether do it in batches` if (twoPercent > 1000 ether) { (success,) = apeBomb.call{value: 1000 ether}(""); remainingToSend = twoPercent - 1000 ether; } else { if (twoPercent > 0) { (success,) = apeBomb.call{value: twoPercent}(""); } } if (!success) revert TransferFailed(); emit WinnerSelected(currentTournamentId, entrant, address(this).balance); emergencyWithdrawTimestamp = 0; unchecked { ++currentTournamentId; currentTarget = currentTarget * 110 / 100; } } 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 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); ArbInfo(arbInfo).configureDelegateYield(msg.sender); } // 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 > currentTarget) 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":"InvalidSender","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":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":"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":"apeBomb","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"arbInfo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"currentTarget","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"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":"remainingToSend","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[{"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
608060405260646004555f6005553480156017575f5ffd5b50601f336023565b605e565b6001600160a01b0316638b78c6d819819055805f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b61111d8061006b5f395ff3fe608060405260043610610129575f3560e01c8063715018a6116100a8578063ae9285211161006d578063ae92852114610483578063c28f7c3b146104aa578063f04e283e146104be578063f2fde38b146104d1578063fc8e7504146104e4578063fee81cf4146104f9575f5ffd5b8063715018a61461040f5780637503e1b7146104175780637b802338146104425780638da5cb5b14610456578063aa8d5e1c1461046e575f5ffd5b80633bab39c9116100ee5780633bab39c91461038e57806347ce07cc146103a257806352a5f1f8146103c957806354d1f13d146103e85780635d799f87146103f0575f5ffd5b8063085d4883146102a657806323383e8a146102ea578063256929621461030d57806339148c53146103155780633a4d29a01461032a575f5ffd5b366102a25773c1932844edcc3193ae2622089c4b57ae5f023d7e19330161016357604051636edaef2f60e11b815260040160405180910390fd5b6005541561029857683635c9adc5dea000006005541115610216576040515f9073c1932844edcc3193ae2622089c4b57ae5f023d7f90683635c9adc5dea00000908381818185875af1925050503d805f81146101da576040519150601f19603f3d011682016040523d82523d5f602084013e6101df565b606091505b5050905080610201576040516312171d8360e31b815260040160405180910390fd5b5060058054683635c9adc5de9fffff19019055005b6005546040515f9173c1932844edcc3193ae2622089c4b57ae5f023d7f918381818185875af1925050503d805f811461026a576040519150601f19603f3d011682016040523d82523d5f602084013e61026f565b606091505b5050905080610291576040516312171d8360e31b815260040160405180910390fd5b505f600555005b6102a061052a565b005b5f5ffd5b3480156102b1575f5ffd5b506102cd7352deaa1c84233f7bb8c8a45baede41091c61650681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102f5575f5ffd5b506102ff60025481565b6040519081526020016102e1565b6102a0610746565b348015610320575f5ffd5b506102ff60045481565b348015610335575f5ffd5b50600354610362906001600160a01b0381169063ffffffff600160a01b8204811691600160c01b90041683565b604080516001600160a01b03909416845263ffffffff92831660208501529116908201526060016102e1565b348015610399575f5ffd5b506102a0610793565b3480156103ad575f5ffd5b506102cd7336825bf3fbdf5a29e2d5148bfe7dcf7b5639e32081565b3480156103d4575f5ffd5b506102a06103e3366004610f27565b610849565b6102a06108e1565b3480156103fb575f5ffd5b506102a061040a366004610f62565b61091a565b6102a0610a25565b348015610422575f5ffd5b506102ff610431366004610f93565b5f6020819052908152604090205481565b34801561044d575f5ffd5b506102cd606581565b348015610461575f5ffd5b50638b78c6d819546102cd565b348015610479575f5ffd5b506102ff60055481565b34801561048e575f5ffd5b506102cd73c1932844edcc3193ae2622089c4b57ae5f023d7f81565b3480156104b5575f5ffd5b506102a0610a38565b6102a06104cc366004610faa565b610a88565b6102a06104df366004610faa565b610ac2565b3480156104ef575f5ffd5b506102ff60015481565b348015610504575f5ffd5b506102ff610513366004610faa565b63389a75e1600c9081525f91909152602090205490565b3415806105475750610544670de0b6b3a764000034610fde565b15155b8061055a5750683635c9adc5dea0000034115b156105785760405163162908e360e11b815260040160405180910390fd5b5f61058b670de0b6b3a764000034611005565b905061059681610ae8565b6040805142602082015243918101919091523360608201524760808201525f9060a00160408051808303601f19018152908290528051602090910120631711922960e31b82527352deaa1c84233f7bb8c8a45baede41091c616506600483015291505f907336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3209063b88c914890602401602060405180830381865afa158015610634573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106589190611018565b6040516319cb825f60e01b81527352deaa1c84233f7bb8c8a45baede41091c6165066004820152602481018490529091507336825bf3fbdf5a29e2d5148bfe7dcf7b5639e320906319cb825f906001600160801b0384169060440160206040518083038185885af11580156106cf573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106f4919061103e565b50604051630f06e20760e21b8152336004820152606590633c1b881c906024015f604051808303815f87803b15801561072b575f5ffd5b505af115801561073d573d5f5f3e3d5ffd5b50505050505050565b5f6202a30067ffffffffffffffff164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f5fa250565b61079b610bdf565b6002545f036107bd5760405163702e107b60e11b815260040160405180910390fd5b6002544210156107e05760405163312df54960e21b815260040160405180910390fd5b6040515f90339047908381818185875af1925050503d805f811461081f576040519150601f19603f3d011682016040523d82523d5f602084013e610824565b606091505b5050905080610846576040516312171d8360e31b815260040160405180910390fd5b50565b7336825bf3fbdf5a29e2d5148bfe7dcf7b5639e32061086c565b60405180910390fd5b336001600160a01b038216146108d05760405162461bcd60e51b815260206004820152602360248201527f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460448201526234b7b760e91b6064820152608401610863565b6108db848484610bf9565b50505050565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f5fa2565b610922610bdf565b6001600160a01b03821661094957604051630f58058360e11b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa15801561098d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109b19190611059565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018390529192509084169063a9059cbb906044016020604051808303815f875af1158015610a01573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108db9190611070565b610a2d610bdf565b610a365f610e64565b565b610a40610bdf565b610a4e426301e1338061108f565b60028190556040519081527f6c51e0e9648746b65a27425fd08714243ff8799934a67ee370cde94eb5e415039060200160405180910390a1565b610a90610bdf565b63389a75e1600c52805f526020600c208054421115610ab657636f5e88185f526004601cfd5b5f905561084681610e64565b610aca610bdf565b8060601b610adf57637448fbae5f526004601cfd5b61084681610e64565b6001545f9081526020819052604081205490610b05606484611005565b610b1090600161108f565b90505f5b81811015610b5357600180545f9081526020818152604080832060648602880184528401909152902080546001600160a01b0319163317905501610b14565b5060045482840190811115610b7b57604051636d7a147360e01b815260040160405180910390fd5b600180545f908152602081905260409020829055805433917f67f18c62d694f27ab65863682a2757fc3881081d5274f7fe7deb533a5ef32b9e908690610bc190866110a8565b6040805192835260208301919091520160405180910390a350505050565b638b78c6d819543314610a36576382b429005f526004601cfd5b60045481905f90610c0a9083610fde565b6001545f908152602081905260409020549091508110610c2b575050505050565b5f610c3582610ea1565b90506001600160a01b038116610c4d57505050505050565b5f610c6168056bc75e2d6310000047611005565b610c7390671bc16d674ec800006110bb565b90505f6001600160a01b038316610c8a83476110a8565b6040515f81818185875af1925050503d805f8114610cc3576040519150601f19603f3d011682016040523d82523d5f602084013e610cc8565b606091505b5050905080610cea576040516312171d8360e31b815260040160405180910390fd5b683635c9adc5dea00000821115610d7b5760405173c1932844edcc3193ae2622089c4b57ae5f023d7f90683635c9adc5dea00000905f81818185875af1925050503d805f8114610d55576040519150601f19603f3d011682016040523d82523d5f602084013e610d5a565b606091505b50909150610d739050683635c9adc5dea00000836110a8565b600555610ddd565b8115610ddd5760405173c1932844edcc3193ae2622089c4b57ae5f023d7f9083905f81818185875af1925050503d805f8114610dd2576040519150601f19603f3d011682016040523d82523d5f602084013e610dd7565b606091505b50909150505b80610dfb576040516312171d8360e31b815260040160405180910390fd5b826001600160a01b03166001547ffee5b04775e1cd2311ed22cd00f5d2403aff38ff6f71d6d393f51854ed6bc98647604051610e3991815260200190565b60405180910390a35f6002556001805481019055600454606490606e02046004555050505050505050565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a355565b5f815b600180545f90815260208181526040808320858452909301905220546001600160a01b03168015610ed6579392505050565b815f03610ee657505f9392505050565b50610ef0816110d2565b9050610ea4565b67ffffffffffffffff81168114610846575f5ffd5b80356001600160a01b0381168114610f22575f5ffd5b919050565b5f5f5f60608486031215610f39575f5ffd5b8335610f4481610ef7565b9250610f5260208501610f0c565b9150604084013590509250925092565b5f5f60408385031215610f73575f5ffd5b610f7c83610f0c565b9150610f8a60208401610f0c565b90509250929050565b5f60208284031215610fa3575f5ffd5b5035919050565b5f60208284031215610fba575f5ffd5b610fc382610f0c565b9392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610fec57610fec610fca565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f8261101357611013610fca565b500490565b5f60208284031215611028575f5ffd5b81516001600160801b0381168114610fc3575f5ffd5b5f6020828403121561104e575f5ffd5b8151610fc381610ef7565b5f60208284031215611069575f5ffd5b5051919050565b5f60208284031215611080575f5ffd5b81518015158114610fc3575f5ffd5b808201808211156110a2576110a2610ff1565b92915050565b818103818111156110a2576110a2610ff1565b80820281158282048414176110a2576110a2610ff1565b5f816110e0576110e0610ff1565b505f19019056fea264697066735822122009768e22b4010bc30e0e5d8de3e87e520a9921862d36b4dfa5b5157b9aaaab3e64736f6c634300081c0033
Deployed Bytecode
0x608060405260043610610129575f3560e01c8063715018a6116100a8578063ae9285211161006d578063ae92852114610483578063c28f7c3b146104aa578063f04e283e146104be578063f2fde38b146104d1578063fc8e7504146104e4578063fee81cf4146104f9575f5ffd5b8063715018a61461040f5780637503e1b7146104175780637b802338146104425780638da5cb5b14610456578063aa8d5e1c1461046e575f5ffd5b80633bab39c9116100ee5780633bab39c91461038e57806347ce07cc146103a257806352a5f1f8146103c957806354d1f13d146103e85780635d799f87146103f0575f5ffd5b8063085d4883146102a657806323383e8a146102ea578063256929621461030d57806339148c53146103155780633a4d29a01461032a575f5ffd5b366102a25773c1932844edcc3193ae2622089c4b57ae5f023d7e19330161016357604051636edaef2f60e11b815260040160405180910390fd5b6005541561029857683635c9adc5dea000006005541115610216576040515f9073c1932844edcc3193ae2622089c4b57ae5f023d7f90683635c9adc5dea00000908381818185875af1925050503d805f81146101da576040519150601f19603f3d011682016040523d82523d5f602084013e6101df565b606091505b5050905080610201576040516312171d8360e31b815260040160405180910390fd5b5060058054683635c9adc5de9fffff19019055005b6005546040515f9173c1932844edcc3193ae2622089c4b57ae5f023d7f918381818185875af1925050503d805f811461026a576040519150601f19603f3d011682016040523d82523d5f602084013e61026f565b606091505b5050905080610291576040516312171d8360e31b815260040160405180910390fd5b505f600555005b6102a061052a565b005b5f5ffd5b3480156102b1575f5ffd5b506102cd7352deaa1c84233f7bb8c8a45baede41091c61650681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102f5575f5ffd5b506102ff60025481565b6040519081526020016102e1565b6102a0610746565b348015610320575f5ffd5b506102ff60045481565b348015610335575f5ffd5b50600354610362906001600160a01b0381169063ffffffff600160a01b8204811691600160c01b90041683565b604080516001600160a01b03909416845263ffffffff92831660208501529116908201526060016102e1565b348015610399575f5ffd5b506102a0610793565b3480156103ad575f5ffd5b506102cd7336825bf3fbdf5a29e2d5148bfe7dcf7b5639e32081565b3480156103d4575f5ffd5b506102a06103e3366004610f27565b610849565b6102a06108e1565b3480156103fb575f5ffd5b506102a061040a366004610f62565b61091a565b6102a0610a25565b348015610422575f5ffd5b506102ff610431366004610f93565b5f6020819052908152604090205481565b34801561044d575f5ffd5b506102cd606581565b348015610461575f5ffd5b50638b78c6d819546102cd565b348015610479575f5ffd5b506102ff60055481565b34801561048e575f5ffd5b506102cd73c1932844edcc3193ae2622089c4b57ae5f023d7f81565b3480156104b5575f5ffd5b506102a0610a38565b6102a06104cc366004610faa565b610a88565b6102a06104df366004610faa565b610ac2565b3480156104ef575f5ffd5b506102ff60015481565b348015610504575f5ffd5b506102ff610513366004610faa565b63389a75e1600c9081525f91909152602090205490565b3415806105475750610544670de0b6b3a764000034610fde565b15155b8061055a5750683635c9adc5dea0000034115b156105785760405163162908e360e11b815260040160405180910390fd5b5f61058b670de0b6b3a764000034611005565b905061059681610ae8565b6040805142602082015243918101919091523360608201524760808201525f9060a00160408051808303601f19018152908290528051602090910120631711922960e31b82527352deaa1c84233f7bb8c8a45baede41091c616506600483015291505f907336825bf3fbdf5a29e2d5148bfe7dcf7b5639e3209063b88c914890602401602060405180830381865afa158015610634573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106589190611018565b6040516319cb825f60e01b81527352deaa1c84233f7bb8c8a45baede41091c6165066004820152602481018490529091507336825bf3fbdf5a29e2d5148bfe7dcf7b5639e320906319cb825f906001600160801b0384169060440160206040518083038185885af11580156106cf573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106f4919061103e565b50604051630f06e20760e21b8152336004820152606590633c1b881c906024015f604051808303815f87803b15801561072b575f5ffd5b505af115801561073d573d5f5f3e3d5ffd5b50505050505050565b5f6202a30067ffffffffffffffff164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f5fa250565b61079b610bdf565b6002545f036107bd5760405163702e107b60e11b815260040160405180910390fd5b6002544210156107e05760405163312df54960e21b815260040160405180910390fd5b6040515f90339047908381818185875af1925050503d805f811461081f576040519150601f19603f3d011682016040523d82523d5f602084013e610824565b606091505b5050905080610846576040516312171d8360e31b815260040160405180910390fd5b50565b7336825bf3fbdf5a29e2d5148bfe7dcf7b5639e32061086c565b60405180910390fd5b336001600160a01b038216146108d05760405162461bcd60e51b815260206004820152602360248201527f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460448201526234b7b760e91b6064820152608401610863565b6108db848484610bf9565b50505050565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f5fa2565b610922610bdf565b6001600160a01b03821661094957604051630f58058360e11b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa15801561098d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109b19190611059565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018390529192509084169063a9059cbb906044016020604051808303815f875af1158015610a01573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108db9190611070565b610a2d610bdf565b610a365f610e64565b565b610a40610bdf565b610a4e426301e1338061108f565b60028190556040519081527f6c51e0e9648746b65a27425fd08714243ff8799934a67ee370cde94eb5e415039060200160405180910390a1565b610a90610bdf565b63389a75e1600c52805f526020600c208054421115610ab657636f5e88185f526004601cfd5b5f905561084681610e64565b610aca610bdf565b8060601b610adf57637448fbae5f526004601cfd5b61084681610e64565b6001545f9081526020819052604081205490610b05606484611005565b610b1090600161108f565b90505f5b81811015610b5357600180545f9081526020818152604080832060648602880184528401909152902080546001600160a01b0319163317905501610b14565b5060045482840190811115610b7b57604051636d7a147360e01b815260040160405180910390fd5b600180545f908152602081905260409020829055805433917f67f18c62d694f27ab65863682a2757fc3881081d5274f7fe7deb533a5ef32b9e908690610bc190866110a8565b6040805192835260208301919091520160405180910390a350505050565b638b78c6d819543314610a36576382b429005f526004601cfd5b60045481905f90610c0a9083610fde565b6001545f908152602081905260409020549091508110610c2b575050505050565b5f610c3582610ea1565b90506001600160a01b038116610c4d57505050505050565b5f610c6168056bc75e2d6310000047611005565b610c7390671bc16d674ec800006110bb565b90505f6001600160a01b038316610c8a83476110a8565b6040515f81818185875af1925050503d805f8114610cc3576040519150601f19603f3d011682016040523d82523d5f602084013e610cc8565b606091505b5050905080610cea576040516312171d8360e31b815260040160405180910390fd5b683635c9adc5dea00000821115610d7b5760405173c1932844edcc3193ae2622089c4b57ae5f023d7f90683635c9adc5dea00000905f81818185875af1925050503d805f8114610d55576040519150601f19603f3d011682016040523d82523d5f602084013e610d5a565b606091505b50909150610d739050683635c9adc5dea00000836110a8565b600555610ddd565b8115610ddd5760405173c1932844edcc3193ae2622089c4b57ae5f023d7f9083905f81818185875af1925050503d805f8114610dd2576040519150601f19603f3d011682016040523d82523d5f602084013e610dd7565b606091505b50909150505b80610dfb576040516312171d8360e31b815260040160405180910390fd5b826001600160a01b03166001547ffee5b04775e1cd2311ed22cd00f5d2403aff38ff6f71d6d393f51854ed6bc98647604051610e3991815260200190565b60405180910390a35f6002556001805481019055600454606490606e02046004555050505050505050565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a355565b5f815b600180545f90815260208181526040808320858452909301905220546001600160a01b03168015610ed6579392505050565b815f03610ee657505f9392505050565b50610ef0816110d2565b9050610ea4565b67ffffffffffffffff81168114610846575f5ffd5b80356001600160a01b0381168114610f22575f5ffd5b919050565b5f5f5f60608486031215610f39575f5ffd5b8335610f4481610ef7565b9250610f5260208501610f0c565b9150604084013590509250925092565b5f5f60408385031215610f73575f5ffd5b610f7c83610f0c565b9150610f8a60208401610f0c565b90509250929050565b5f60208284031215610fa3575f5ffd5b5035919050565b5f60208284031215610fba575f5ffd5b610fc382610f0c565b9392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610fec57610fec610fca565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f8261101357611013610fca565b500490565b5f60208284031215611028575f5ffd5b81516001600160801b0381168114610fc3575f5ffd5b5f6020828403121561104e575f5ffd5b8151610fc381610ef7565b5f60208284031215611069575f5ffd5b5051919050565b5f60208284031215611080575f5ffd5b81518015158114610fc3575f5ffd5b808201808211156110a2576110a2610ff1565b92915050565b818103818111156110a2576110a2610ff1565b80820281158282048414176110a2576110a2610ff1565b5f816110e0576110e0610ff1565b505f19019056fea264697066735822122009768e22b4010bc30e0e5d8de3e87e520a9921862d36b4dfa5b5157b9aaaab3e64736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
APE | 100.00% | $0.689916 | 88.4326 | $61.01 |
[ 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.