pragma solidity ^0.4.25; contract CoinFlipper{ using SafeMath for uint256; uint256 private totalSendDividends; uint256 public maxBet = 5e18; uint256 public minBet = 0.1e18; uint256 public minContractBalance = 100e18; uint256 public minBetForJackpot = 0.1e18; uint256 public jackpotBalance; uint256 public nextPayout; uint256 public ownerDeposit; uint256 private lastBlock; address[2] public owners; address[2] public candidates; address public mainContract; bool public paused; mapping (address => Bet) private usersBets; struct Bet { uint256 blockNumber; uint8 coin; uint256 bet; } modifier onlyOwners() { require(msg.sender == owners[0] || msg.sender == owners[1]); _; } modifier sendDividends(){ _; if(getContractBalance() > minContractBalance && now > nextPayout){ uint256 dividends = getContractBalance() - minContractBalance; nextPayout = now.add(7 days); totalSendDividends = totalSendDividends.add(dividends); mainContract.transfer(dividends); emit onSendDividends(dividends, now); } } modifier checkBlockNumber(){ if(block.number.sub(usersBets[msg.sender].blockNumber) > 250){ uint256 bet = usersBets[msg.sender].bet; delete usersBets[msg.sender]; emit Result(msg.sender, 0, 1001, jackpotBalance, 0, bet, now); } else{ _; } } constructor(address mainContractAddress, address secondOwner) public payable{ owners[0] = msg.sender; owners[1] = secondOwner; ownerDeposit = msg.value; mainContract = mainContractAddress; jackpotBalance = jackpotBalance.add(msg.value.div(100)); nextPayout = now.add(7 days); } function playGame(uint8 coin) public payable sendDividends checkBlockNumber{ uint256 bet = msg.value; require(getContractBalance() > bet.add(bet).add(jackpotBalance), "Not enough ETH in contract"); require(paused == false, "Game was stopped"); require(bet >= minBet && bet <= maxBet, "Amount should be within range"); require(usersBets[msg.sender].bet == 0, "You have already bet"); usersBets[msg.sender].bet = bet; usersBets[msg.sender].blockNumber = block.number; usersBets[msg.sender].coin = coin; emit PlaceBet(msg.sender, bet, block.number + 250, now); } function getResult() public checkBlockNumber{ require(usersBets[msg.sender].bet > 0, "Please make a bet"); require(blockhash(usersBets[msg.sender].blockNumber) != 0, "You did not have time to open your bet"); address player = msg.sender; uint256 bet = usersBets[msg.sender].bet; uint8 coin = usersBets[msg.sender].coin; uint256 totalWinAmount; uint256 winRate = getWinningRate(usersBets[msg.sender].bet); uint256 randomNumber = random(1000); if(randomNumber >= 499 && coin == 0){ totalWinAmount = totalWinAmount.add(bet.add(bet.mul(winRate).div(100))); jackpotBalance = jackpotBalance.add(bet.mul(100 - winRate).div(1000)); } if(randomNumber <= 499 && coin == 1){ totalWinAmount = totalWinAmount.add(bet.add(bet.mul(winRate).div(100))); jackpotBalance = jackpotBalance.add(bet.mul(100 - winRate).div(1000)); } if(bet >= minBetForJackpot && randomNumber == 0 && jackpotBalance > 0){ totalWinAmount = totalWinAmount.add(jackpotBalance); jackpotBalance = jackpotBalance.sub(jackpotBalance); } if(totalWinAmount > 0){ player.transfer(totalWinAmount); } else{ jackpotBalance = jackpotBalance.add(bet.div(100)); } delete usersBets[msg.sender]; emit Result(player, totalWinAmount, randomNumber, jackpotBalance, winRate, bet, now); } function getWinningRate(uint256 eth) public view returns(uint8){ uint256 x = maxBet.sub(minBet).div(4); uint8 rate; if(eth >= minBet && eth <= minBet.add(x)){ rate = 95; } else if(eth >= minBet.add(x.mul(1)) && eth <= minBet.add(x.mul(2))){ rate = 96; } else if(eth >= minBet.add(x.mul(2)) && eth <= minBet.add(x.mul(3))){ rate = 97; } else if(eth >= minBet.add(x.mul(3)) && eth <= minBet.add(x.mul(4))){ rate = 98; } else{ rate = 95; } return rate; } function getContractBalance() public view returns (uint256) { return address(this).balance; } function random(uint256 max) public view returns(uint256){ return uint256(keccak256(abi.encode(blockhash(usersBets[msg.sender].blockNumber), now))) % max; } function deposit() public payable onlyOwners{ uint256 senderValue = msg.value; ownerDeposit = ownerDeposit.add(senderValue); jackpotBalance = jackpotBalance.add(senderValue.mul(1).div(100)); } function sendOwnerDeposit() public payable onlyOwners{ uint256 contractBalance = getContractBalance(); if(contractBalance >= ownerDeposit){ owners[0].transfer(ownerDeposit); } else{ owners[0].transfer(contractBalance); jackpotBalance = 0; paused = true; } } function getTotalSendDividends() public view onlyOwners returns (uint256){ return totalSendDividends; } function pauseGame(bool option) public onlyOwners{ paused = option; } function setMinBet(uint256 eth) public onlyOwners{ minBet = eth; } function setMaxBet(uint256 eth) public onlyOwners{ maxBet = eth; } function setMinBetForJackpot(uint256 eth) public onlyOwners{ minBetForJackpot = eth; } function setMinContractBalance(uint256 eth) public onlyOwners{ minContractBalance = eth; } function transferOwnership(address newOwnerAddress, uint8 k) public onlyOwners { //Set new candidate for future owner candidates[k] = newOwnerAddress; } function confirmOwner(uint8 k) public { //Confirm new candidate, if sender is first candidate, then first candidate will be set first owner require(msg.sender == candidates[k]); owners[k] = candidates[k]; } event onSendDividends( uint256 dividends, uint256 timestamp ); event PlaceBet( address indexed player, uint256 bet, uint256 lastBlock, uint256 timestamp ); event Result( address indexed palyerAddress, uint256 totalWinAmount, uint256 random, uint256 jackpotBalance, uint256 winRate, uint256 bet, uint256 timestamp ); } library SafeMath { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0); uint256 c = a / b; return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } }
0.4.25