pragma solidity ^0.4.24;
contract Lottery{
/*=================================
= MODIFIERS =
=================================*/
// Only owner allowed.
modifier onlyOwner()
{
require(msg.sender == owner);
_;
}
// The tokens can never be stolen.
modifier notPooh(address aContract)
{
require(aContract != address(poohContract));
_;
}
modifier isOpenToPublic()
{
require(openToPublic);
_;
}
modifier onlyHuman()
{
require (msg.sender == tx.origin);
_;
}
/*==============================
= EVENTS =
==============================*/
event Deposit(
uint256 amount,
address depositer
);
event WinnerPaid(
uint256 amount,
address winner
);
/*=====================================
= CONFIGURABLES =
=====================================*/
POOH poohContract; //a reference to the POOH contract
address owner;
bool openToPublic = false; //Is this lottery open for public use
uint256 ticketNumber = 0; //Starting ticket number
uint256 winningNumber; //The randomly generated winning ticket
/*=======================================
= PUBLIC FUNCTIONS =
=======================================*/
constructor() public
{
poohContract = POOH(0x4C29d75cc423E8Adaa3839892feb66977e295829);
openToPublic = false;
owner = msg.sender;
}
/* Fallback function allows anyone to send money for the cost of gas which
goes into the pool. Used by withdraw/dividend payouts.*/
function() payable public { }
function deposit()
isOpenToPublic()
onlyHuman()
payable public
{
//You have to send more than 0.001 ETH
require(msg.value >= 1000000000000000);
address customerAddress = msg.sender;
//Use deposit to purchase POOH tokens
poohContract.buy.value(msg.value)(customerAddress);
emit Deposit(msg.value, msg.sender);
//if entry more than 0.001 ETH
if(msg.value > 1000000000000000)
{
uint extraTickets = SafeMath.div(msg.value, 1000000000000000); //each additional entry is 0.001 ETH
//Compute how many positions they get by how many POOH they transferred in.
ticketNumber += extraTickets;
}
//if when we have a winner...
if(ticketNumber >= winningNumber)
{
//sell all tokens and cash out earned dividends
poohContract.exit();
//lotteryFee
payDev(owner);
//payout winner
payWinner(customerAddress);
//buy more POOH tokens with the remaining balance
poohContract.buy.value(address(this).balance)(customerAddress);
//rinse and repeat
resetLottery();
}
else
{
ticketNumber++;
}
}
//Number of POOH tokens currently in the Lottery pool
function myTokens() public view returns(uint256)
{
return poohContract.myTokens();
}
//Lottery's divs
function myDividends() public view returns(uint256)
{
return poohContract.myDividends(true);
}
//Lottery's ETH balance
function ethBalance() public view returns (uint256)
{
return address(this).balance;
}
/*======================================
= OWNER ONLY FUNCTIONS =
======================================*/
//give the people access to play
function openToThePublic()
onlyOwner()
public
{
openToPublic = true;
resetLottery();
}
/* A trap door for when someone sends tokens other than the intended ones so the overseers
can decide where to send them. (credit: Doublr Contract) */
function returnAnyERC20Token(address tokenAddress, address tokenOwner, uint tokens)
public
onlyOwner()
notPooh(tokenAddress)
returns (bool success)
{
return ERC20Interface(tokenAddress).transfer(tokenOwner, tokens);
}
/*======================================
= INTERNAL FUNCTIONS =
======================================*/
//pay winner
function payWinner(address winner) internal
{
//need to have 0.05 ETH balance left over for the next round.
uint balance = SafeMath.sub(address(this).balance, 50000000000000000);
winner.transfer(balance);
emit WinnerPaid(balance, winner);
}
//donate to dev
function payDev(address dev) internal
{
uint balance = SafeMath.div(address(this).balance, 10);
dev.transfer(balance);
}
function resetLottery() internal
isOpenToPublic()
{
ticketNumber = 1;
winningNumber = uint256(keccak256(block.timestamp, block.difficulty))%300;
}
}
//Need to ensure this contract can send tokens to people
contract ERC20Interface
{
function transfer(address to, uint256 tokens) public returns (bool success);
}
//Need to ensure the Lottery contract knows what a POOH token is
contract POOH
{
function buy(address) public payable returns(uint256);
function exit() public;
function myTokens() public view returns(uint256);
function myDividends(bool) public view returns(uint256);
}
library SafeMath {
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256)
{
uint256 c = a / b;
return c;
}
/**
* @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
}
{
"compilationTarget": {
"Lottery.sol": "Lottery"
},
"evmVersion": "byzantium",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":false,"inputs":[],"name":"openToThePublic","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"myDividends","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ethBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"myTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenAddress","type":"address"},{"name":"tokenOwner","type":"address"},{"name":"tokens","type":"uint256"}],"name":"returnAnyERC20Token","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"depositer","type":"address"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"winner","type":"address"}],"name":"WinnerPaid","type":"event"}]