Address Contract Partially Verified
Address
0x4C0b9B7b3e290B793474c533C7AC90262bb69971
Balance
0 ETH
Nonce
1
Code Size
5191 bytes
Creator
0xEa04F65f...E266 at tx 0x84fd37a0...daf6c6
Indexed Transactions
0
Contract Bytecode
5191 bytes
0x6080604052600436106101445760003560e01c80638456cb59116100b6578063b79fba271161006f578063b79fba2714610365578063bf4c1d1e14610392578063c465e49f146103c8578063e9bf95a2146103dd578063ec5ae157146103fd578063f2fde38b146104135761014b565b80638456cb59146102b65780638da5cb5b146102cb57806391b7f5ed146102fd57806393e84cd91461031d578063aa3bf60e14610325578063acec338a146103455761014b565b80633f4ba83a116101085780633f4ba83a146102225780634ec18db9146102375780635c975abb1461024c5780635cad65a11461026b57806369c1a7ed1461028b578063715018a6146102a15761014b565b806302fb0c5e1461016657806312065fe01461019557806336118b52146101b25780633b98d8e6146101d25780633c042fb2146102025761014b565b3661014b57005b34801561015757600080fd5b5061016433600036610433565b005b34801561017257600080fd5b506004546101809060ff1681565b60405190151581526020015b60405180910390f35b3480156101a157600080fd5b50475b60405190815260200161018c565b3480156101be57600080fd5b506101646101cd3660046111ba565b610658565b3480156101de57600080fd5b506101806101ed3660046111ea565b60066020526000908152604090205460ff1681565b34801561020e57600080fd5b5061016461021d3660046111ea565b61079a565b34801561022e57600080fd5b50610164610901565b34801561024357600080fd5b506005546101a4565b34801561025857600080fd5b50600054600160a01b900460ff16610180565b34801561027757600080fd5b50610180610286366004611203565b610913565b34801561029757600080fd5b506101a460025481565b3480156102ad57600080fd5b50610164610929565b3480156102c257600080fd5b5061016461093b565b3480156102d757600080fd5b506000546001600160a01b03165b6040516001600160a01b03909116815260200161018c565b34801561030957600080fd5b506101646103183660046111ea565b61094b565b61016461098f565b34801561033157600080fd5b50610180610340366004611203565b610cfe565b34801561035157600080fd5b5061016461036036600461122f565b610d34565b34801561037157600080fd5b50610385610380366004611258565b610d7d565b60405161018c919061127a565b34801561039e57600080fd5b506102e56103ad3660046111ea565b6007602052600090815260409020546001600160a01b031681565b3480156103d457600080fd5b506101a4600581565b3480156103e957600080fd5b506101a46103f8366004611203565b610e77565b34801561040957600080fd5b506101a460035481565b34801561041f57600080fd5b5061016461042e3660046112be565b610ef9565b6000546001600160a01b0384811691161461048e5760405162461bcd60e51b815260206004820152601660248201527513db9b1e481bdddb995c8818d85b8819195c1bdcda5d60521b60448201526064015b60405180910390fd5b80158015906104a557506104a36020826112f1565b155b6104e25760405162461bcd60e51b815260206004820152600e60248201526d092dcecc2d8d2c840d8cadccee8d60931b6044820152606401610485565b60005b6104f060208361131b565b811015610652576000838361050684602061132f565b90610512856001611346565b61051d90602061132f565b9261052a93929190611359565b81019061053791906111ea565b60008181526006602052604090205490915060ff161561058b5760405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e481a5b881c1bdbdb608a1b6044820152606401610485565b6001600160a01b03851660008181526000805160206113f28339815191526020908152604080832085845282528083204390556005805460018082019092557f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00186905560068352818420805460ff19169091179055600790915280822080546001600160a01b031916841790555183917f2afc8e88f530f9a4d426e1d9aa85c29ec6e38951a150424846f9b0415b15f33b91a3508061064a81611383565b9150506104e5565b50505050565b610660610f37565b610668610f64565b6001600160a01b0381166106b05760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610485565b478211156106f75760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610485565b6000816001600160a01b03168360405160006040518083038185875af1925050503d8060008114610744576040519150601f19603f3d011682016040523d82523d6000602084013e610749565b606091505b505090508061078c5760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606401610485565b5061079660018055565b5050565b6107a2610f37565b60008181526006602052604090205460ff166107ee5760405162461bcd60e51b815260206004820152600b60248201526a139bdd081a5b881c1bdbdb60aa1b6044820152606401610485565b60005b6005548110156108a757816005828154811061080f5761080f61139c565b906000526020600020015403610895576005805461082f906001906113b2565b8154811061083f5761083f61139c565b90600052602060002001546005828154811061085d5761085d61139c565b600091825260209091200155600580548061087a5761087a6113c5565b600190038181906000526020600020016000905590556108a7565b8061089f81611383565b9150506107f1565b506000818152600660205260408120805460ff19169055546108d3906001600160a01b03168083610f8e565b60405181907f1dd020ab4e46cb183ee32c514b343e9a803ba5ce0fabf281f39c0f0a37071bd690600090a250565b610909610f37565b610911611010565b565b600061091f8383610cfe565b1590505b92915050565b610931610f37565b6109116000611065565b610943610f37565b6109116110b5565b610953610f37565b60028190556040518181527f6bfd5e75539a9d2626425a2e2922675256b219fe546d63dad56011759b9a2f66906020015b60405180910390a150565b610997610f64565b61099f6110f8565b60045460ff166109e45760405162461bcd60e51b815260206004820152601060248201526f4c6f747465727920696e61637469766560801b6044820152606401610485565b600254341015610a2d5760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b6044820152606401610485565b600554610a725760405162461bcd60e51b81526020600482015260136024820152724e6f207072697a657320617661696c61626c6560681b6044820152606401610485565b60038054906000610a8283611383565b91905055506000444260035433604051602001610acb949392919093845260208401929092526040830152606090811b6bffffffffffffffffffffffff19169082015260740190565b60408051601f198184030181529190528051602090910120600554909150600090610af690836112f1565b9050600060058281548110610b0d57610b0d61139c565b60009182526020808320909101548083526007909152604090912054600580549293506001600160a01b0390911691610b48906001906113b2565b81548110610b5857610b5861139c565b906000526020600020015460058481548110610b7657610b7661139c565b6000918252602090912001556005805480610b9357610b936113c5565b600082815260208082208301600019908101839055909201909255838252600681526040808320805460ff191690556007909152902080546001600160a01b0319169055610be2813384610f8e565b60035460408051348152602081018790523392917f4011fff102fa79e54900316bba9ba8fa8bcdc15e023292edd636c727dfe3c87d910160405180910390a3600354604051839133917f435d496d95c2fa344731362e4067994acb8cb72a4aa34b318e70f31c41da5d5e90600090a4600254341115610cf1576002546000903390610c6d90346113b2565b604051600081818185875af1925050503d8060008114610ca9576040519150601f19603f3d011682016040523d82523d6000602084013e610cae565b606091505b5050905080610cef5760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b6044820152606401610485565b505b5050505061091160018055565b6001600160a01b039190911660009081526000805160206113f28339815191526020908152604080832093835292905220541590565b610d3c610f37565b6004805460ff19168215159081179091556040519081527f18480802bce25a27d61b6c3a1c5a3d200820627e87b0c2b385c763edd2531cd190602001610984565b60606000610d8b8385611346565b600554909150811115610d9d57506005545b6005548410610dbc575050604080516000815260208101909152610923565b6000610dc885836113b2565b67ffffffffffffffff811115610de057610de06113db565b604051908082528060200260200182016040528015610e09578160200160208202803683370190505b509050845b82811015610e6e5760058181548110610e2957610e2961139c565b9060005260206000200154828783610e4191906113b2565b81518110610e5157610e5161139c565b602090810291909101015280610e6681611383565b915050610e0e565b50949350505050565b6001600160a01b03821660009081526000805160206113f283398151915260209081526040808320848452909152812054808203610ec8576040516362ef5a1960e01b815260040160405180910390fd5b6000610ed482436113b2565b905060058110610ee5576000610ef0565b610ef08160056113b2565b95945050505050565b610f01610f37565b6001600160a01b038116610f2b57604051631e4fbdf760e01b815260006004820152602401610485565b610f3481611065565b50565b6000546001600160a01b031633146109115760405163118cdaa760e01b8152336004820152602401610485565b600260015403610f8757604051633ee5aeb560e01b815260040160405180910390fd5b6002600155565b610f99838383611123565b80826001600160a01b0316846001600160a01b03167ff1d95ed4d1680e6f665104f19c296ae52c1f64cd8114e84d55dc6349dbdafea360405160405180910390a46001600160a01b03831660009081526000805160206113f283398151915260209081526040808320848452909152812055505050565b61101861117b565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6110bd6110f8565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586110483390565b600054600160a01b900460ff16156109115760405163d93c066560e01b815260040160405180910390fd5b61112d8382610cfe565b1561114b576040516362ef5a1960e01b815260040160405180910390fd5b60006111578483610e77565b9050801561065257604051633247baf960e21b815260048101829052602401610485565b600054600160a01b900460ff1661091157604051638dfc202b60e01b815260040160405180910390fd5b6001600160a01b0381168114610f3457600080fd5b600080604083850312156111cd57600080fd5b8235915060208301356111df816111a5565b809150509250929050565b6000602082840312156111fc57600080fd5b5035919050565b6000806040838503121561121657600080fd5b8235611221816111a5565b946020939093013593505050565b60006020828403121561124157600080fd5b8135801515811461125157600080fd5b9392505050565b6000806040838503121561126b57600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b818110156112b257835183529284019291840191600101611296565b50909695505050505050565b6000602082840312156112d057600080fd5b8135611251816111a5565b634e487b7160e01b600052601260045260246000fd5b600082611300576113006112db565b500690565b634e487b7160e01b600052601160045260246000fd5b60008261132a5761132a6112db565b500490565b808202811582820484141761092357610923611305565b8082018082111561092357610923611305565b6000808585111561136957600080fd5b8386111561137657600080fd5b5050820193919092039150565b60006001820161139557611395611305565b5060010190565b634e487b7160e01b600052603260045260246000fd5b8181038181111561092357610923611305565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea282d38759ca2a57f8989aea0c5822bcfbf65ad49415379bdbc35dbb78efd8daa264697066735822122067d8e71726fbe7e08d16031f1b97af7b278846dc2ecb9c0bfca636071cf882b264736f6c63430008140033
Verified Source Code Partial Match
Compiler: v0.8.20+commit.a1b79de6
EVM: paris
Optimization: Yes (200 runs)
PhilipLotteryV67.sol 712 lines
// Sources flattened with hardhat v2.22.5 https://hardhat.org // SPDX-License-Identifier: MIT AND PHUNKY // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File @openzeppelin/contracts/access/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { bool private _paused; /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); /** * @dev The operation failed because the contract is paused. */ error EnforcedPause(); /** * @dev The operation failed because the contract is not paused. */ error ExpectedPause(); /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { if (paused()) { revert EnforcedPause(); } } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) { revert ExpectedPause(); } } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } } // File contracts/V2MainnetUpgrade/EthscriptionsEscrower.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.8.20; library EthscriptionsEscrowerStorage { struct Layout { mapping(address => mapping(bytes32 => uint256)) ethscriptionReceivedOnBlockNumber; } bytes32 internal constant STORAGE_SLOT = keccak256( "ethscriptions.contracts.storage.EthscriptionsEscrowerStorage" ); function s() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } } contract EthscriptionsEscrower { error EthscriptionNotDeposited(); error EthscriptionAlreadyReceivedFromSender(); error InvalidEthscriptionLength(); error AdditionalCooldownRequired(uint256 additionalBlocksNeeded); event ethscriptions_protocol_TransferEthscriptionForPreviousOwner( address indexed previousOwner, address indexed recipient, bytes32 indexed id ); event PotentialEthscriptionDeposited( address indexed owner, bytes32 indexed potentialEthscriptionId ); event PotentialEthscriptionWithdrawn( address indexed owner, bytes32 indexed potentialEthscriptionId ); uint256 public constant ETHSCRIPTION_TRANSFER_COOLDOWN_BLOCKS = 5; function _transferEthscription( address previousOwner, address to, bytes32 ethscriptionId ) internal virtual { _validateTransferEthscription(previousOwner, to, ethscriptionId); emit ethscriptions_protocol_TransferEthscriptionForPreviousOwner( previousOwner, to, ethscriptionId ); _afterTransferEthscription(previousOwner, to, ethscriptionId); } function withdrawEthscription(bytes32 ethscriptionId) internal virtual { _transferEthscription(msg.sender, msg.sender, ethscriptionId); // emit PotentialEthscriptionWithdrawn(msg.sender, ethscriptionId); } function _onPotentialEthscriptionDeposit( address previousOwner, bytes calldata userCalldata ) internal virtual { if (userCalldata.length != 32) revert InvalidEthscriptionLength(); bytes32 potentialEthscriptionId = abi.decode(userCalldata, (bytes32)); if ( userEthscriptionPossiblyStored( previousOwner, potentialEthscriptionId ) ) { revert EthscriptionAlreadyReceivedFromSender(); } EthscriptionsEscrowerStorage.s().ethscriptionReceivedOnBlockNumber[ previousOwner ][potentialEthscriptionId] = block.number; // emit PotentialEthscriptionDeposited(previousOwner, potentialEthscriptionId); } function _validateTransferEthscription( address previousOwner, address to, bytes32 ethscriptionId ) internal view virtual { if ( userEthscriptionDefinitelyNotStored(previousOwner, ethscriptionId) ) { revert EthscriptionNotDeposited(); } uint256 blocksRemaining = blocksRemainingUntilValidTransfer( previousOwner, ethscriptionId ); if (blocksRemaining != 0) { revert AdditionalCooldownRequired(blocksRemaining); } } function _afterTransferEthscription( address previousOwner, address to, bytes32 ethscriptionId ) internal virtual { delete EthscriptionsEscrowerStorage .s() .ethscriptionReceivedOnBlockNumber[previousOwner][ethscriptionId]; } function blocksRemainingUntilValidTransfer( address previousOwner, bytes32 ethscriptionId ) public view virtual returns (uint256) { uint256 receivedBlockNumber = EthscriptionsEscrowerStorage .s() .ethscriptionReceivedOnBlockNumber[previousOwner][ethscriptionId]; if (receivedBlockNumber == 0) { revert EthscriptionNotDeposited(); } uint256 blocksPassed = block.number - receivedBlockNumber; return blocksPassed < ETHSCRIPTION_TRANSFER_COOLDOWN_BLOCKS ? ETHSCRIPTION_TRANSFER_COOLDOWN_BLOCKS - blocksPassed : 0; } function userEthscriptionDefinitelyNotStored( address owner, bytes32 ethscriptionId ) public view virtual returns (bool) { return EthscriptionsEscrowerStorage.s().ethscriptionReceivedOnBlockNumber[ owner ][ethscriptionId] == 0; } function userEthscriptionPossiblyStored( address owner, bytes32 ethscriptionId ) public view virtual returns (bool) { return !userEthscriptionDefinitelyNotStored(owner, ethscriptionId); } } // File contracts/V2MainnetUpgrade/PhilipLotteryV67.sol // Original license: SPDX_License_Identifier: PHUNKY /*********** PhilipLotteryV67 * * ░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░▓▓▓▓░░░░░░▓▓▓▓░░░░░░ * * ░░░░░▒▒██░░░░░░▒▒██░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░████░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░██░░░░░░░░ * * ░░░░░░░░░██████░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░ * ****************************/ pragma solidity 0.8.20; contract PhilipLotteryV67 is EthscriptionsEscrower, Ownable, Pausable, ReentrancyGuard { uint256 public playPrice; uint256 public totalPlays; bool public active; bytes32[] private _prizePool; mapping(bytes32 => bool) public inPool; mapping(bytes32 => address) public depositor; event LotteryPlayed( uint256 indexed playId, address indexed player, uint256 price, uint256 randomSeed ); event PrizeAwarded( uint256 indexed playId, address indexed winner, bytes32 indexed hashId ); event PrizeDeposited(bytes32 indexed hashId, address indexed depositor); event PrizeWithdrawn(bytes32 indexed hashId); event PriceSet(uint256 newPrice); event ActiveToggled(bool active); constructor(uint256 _playPrice) Ownable(msg.sender) { playPrice = _playPrice; active = true; } // ========================================================= // Ethscription Deposits (owner sends ethscriptions here) // ========================================================= fallback() external { _onPotentialEthscriptionDeposit(msg.sender, msg.data); } function _onPotentialEthscriptionDeposit( address previousOwner, bytes calldata userCalldata ) internal override { require(previousOwner == owner(), "Only owner can deposit"); require(userCalldata.length > 0 && userCalldata.length % 32 == 0, "Invalid length"); for (uint256 i = 0; i < userCalldata.length / 32; i++) { bytes32 hashId = abi.decode(userCalldata[i * 32 : (i + 1) * 32], (bytes32)); require(!inPool[hashId], "Already in pool"); // Record in escrow storage (tracks block number for cooldown) EthscriptionsEscrowerStorage.s().ethscriptionReceivedOnBlockNumber[ previousOwner ][hashId] = block.number; // Add to prize pool _prizePool.push(hashId); inPool[hashId] = true; depositor[hashId] = previousOwner; emit PrizeDeposited(hashId, previousOwner); } } // ========================================================= // Play (pay fee, win random ethscription) // ========================================================= function play() external payable nonReentrant whenNotPaused { require(active, "Lottery inactive"); require(msg.value >= playPrice, "Insufficient payment"); require(_prizePool.length > 0, "No prizes available"); totalPlays++; uint256 randomSeed = uint256(keccak256(abi.encodePacked( block.prevrandao, block.timestamp, totalPlays, msg.sender ))); uint256 winIndex = randomSeed % _prizePool.length; bytes32 wonHashId = _prizePool[winIndex]; address dep = depositor[wonHashId]; // Remove from pool (swap with last, then pop) _prizePool[winIndex] = _prizePool[_prizePool.length - 1]; _prizePool.pop(); inPool[wonHashId] = false; delete depositor[wonHashId]; // Transfer ethscription to winner via escrower protocol event _transferEthscription(dep, msg.sender, wonHashId); emit LotteryPlayed(totalPlays, msg.sender, msg.value, randomSeed); emit PrizeAwarded(totalPlays, msg.sender, wonHashId); // Refund excess payment if (msg.value > playPrice) { (bool sent, ) = payable(msg.sender).call{value: msg.value - playPrice}(""); require(sent, "Refund failed"); } } // ========================================================= // View Functions // ========================================================= function poolSize() external view returns (uint256) { return _prizePool.length; } function getPoolItems(uint256 offset, uint256 limit) external view returns (bytes32[] memory) { uint256 end = offset + limit; if (end > _prizePool.length) end = _prizePool.length; if (offset >= _prizePool.length) return new bytes32[](0); bytes32[] memory items = new bytes32[](end - offset); for (uint256 i = offset; i < end; i++) { items[i - offset] = _prizePool[i]; } return items; } function getBalance() external view returns (uint256) { return address(this).balance; } // ========================================================= // Owner Functions // ========================================================= function setPrice(uint256 _price) external onlyOwner { playPrice = _price; emit PriceSet(_price); } function setActive(bool _active) external onlyOwner { active = _active; emit ActiveToggled(_active); } function withdrawETH(uint256 amount, address payable to) external onlyOwner nonReentrant { require(to != address(0), "Invalid address"); require(amount <= address(this).balance, "Insufficient balance"); (bool sent, ) = to.call{value: amount}(""); require(sent, "Transfer failed"); } function withdrawPrize(bytes32 hashId) external onlyOwner { require(inPool[hashId], "Not in pool"); // Find and remove from array for (uint256 i = 0; i < _prizePool.length; i++) { if (_prizePool[i] == hashId) { _prizePool[i] = _prizePool[_prizePool.length - 1]; _prizePool.pop(); break; } } inPool[hashId] = false; // Transfer back to owner _transferEthscription(owner(), owner(), hashId); emit PrizeWithdrawn(hashId); } function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } receive() external payable {} }
Read Contract
ETHSCRIPTION_TRANSFER_COOLDOWN_BLOCKS 0xc465e49f → uint256
active 0x02fb0c5e → bool
blocksRemainingUntilValidTransfer 0xe9bf95a2 → uint256
depositor 0xbf4c1d1e → address
getBalance 0x12065fe0 → uint256
getPoolItems 0xb79fba27 → bytes32[]
inPool 0x3b98d8e6 → bool
owner 0x8da5cb5b → address
paused 0x5c975abb → bool
playPrice 0x69c1a7ed → uint256
poolSize 0x4ec18db9 → uint256
totalPlays 0xec5ae157 → uint256
userEthscriptionDefinitelyNotStored 0xaa3bf60e → bool
userEthscriptionPossiblyStored 0x5cad65a1 → bool
Write Contract 9 functions
These functions modify contract state and require a wallet transaction to execute.
pause 0x8456cb59
No parameters
play 0x93e84cd9
No parameters
renounceOwnership 0x715018a6
No parameters
setActive 0xacec338a
bool _active
setPrice 0x91b7f5ed
uint256 _price
transferOwnership 0xf2fde38b
address newOwner
unpause 0x3f4ba83a
No parameters
withdrawETH 0x36118b52
uint256 amount
address to
withdrawPrize 0x3c042fb2
bytes32 hashId
Recent Transactions
No transactions found for this address