pragma solidity ^0.4.18;
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
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;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
contract TheRichestWins {
using SafeMath for uint256;
address contractOwner;
uint tokenStartPrice = 0.001 ether;
uint tokenStartPrice2 = 0.001483239697419133 ether; // sqrt(2.2) = 1,483239697419133
uint tokenPrice;
uint tokenPrice2;
address tokenOwner;
address tokenOwner2;
uint lastBuyBlock;
uint newRoundDelay = 40;
address public richestPlayer;
uint public highestPrice;
uint public round;
uint public flips;
uint payoutRound;
uint public richestRoundId;
event Transfer(address indexed from, address indexed to, uint256 price);
event NewRound(uint paidPrice, uint win, address winner);
event RichestBonus(uint win, address richestPlayer);
function TheRichestWins() public {
contractOwner = msg.sender;
tokenOwner = address(0);
lastBuyBlock = block.number;
tokenPrice = tokenStartPrice;
tokenPrice2 = tokenStartPrice2;
}
function getRoundId() public view returns(uint) {
return round*1000000+flips;
}
function changeNewRoundDelay(uint delay) public {
require(contractOwner == msg.sender);
newRoundDelay = delay;
}
function changeContractOwner(address newOwner) public {
require(contractOwner == msg.sender);
contractOwner = newOwner;
}
function buyToken() public payable {
address currentOwner;
uint256 currentPrice;
uint256 paidTooMuch;
uint256 payment;
if (tokenPrice < tokenPrice2) {
currentOwner = tokenOwner;
currentPrice = tokenPrice;
require(tokenOwner2 != msg.sender);
} else {
currentOwner = tokenOwner2;
currentPrice = tokenPrice2;
require(tokenOwner != msg.sender);
}
require(msg.value >= currentPrice);
paidTooMuch = msg.value.sub(currentPrice);
payment = currentPrice.div(2);
if (tokenPrice < tokenPrice2) {
tokenPrice = currentPrice.mul(110).div(50);
tokenOwner = msg.sender;
} else {
tokenPrice2 = currentPrice.mul(110).div(50);
tokenOwner2 = msg.sender;
}
lastBuyBlock = block.number;
flips++;
Transfer(currentOwner, msg.sender, currentPrice);
if (currentOwner != address(0)) {
payoutRound = getRoundId()-3;
currentOwner.call.value(payment).gas(24000)();
}
if (paidTooMuch > 0)
msg.sender.transfer(paidTooMuch);
}
function getBlocksToNextRound() public view returns(uint) {
if (lastBuyBlock + newRoundDelay < block.number) {
return 0;
}
return lastBuyBlock + newRoundDelay + 1 - block.number;
}
function getPool() public view returns(uint balance) {
balance = this.balance;
}
function finishRound() public {
require(tokenPrice > tokenStartPrice);
require(lastBuyBlock + newRoundDelay < block.number);
lastBuyBlock = block.number;
address owner = tokenOwner;
uint price = tokenPrice;
if (tokenPrice2>tokenPrice) {
owner = tokenOwner2;
price = tokenPrice2;
}
uint lastPaidPrice = price.mul(50).div(110);
uint win = this.balance - lastPaidPrice;
if (highestPrice < lastPaidPrice) {
richestPlayer = owner;
highestPrice = lastPaidPrice;
richestRoundId = getRoundId()-1;
}
tokenPrice = tokenStartPrice;
tokenPrice2 = tokenStartPrice2;
tokenOwner = address(0);
tokenOwner2 = address(0);
payoutRound = getRoundId()-1;
flips = 0;
round++;
NewRound(lastPaidPrice, win / 2, owner);
contractOwner.transfer((this.balance - (lastPaidPrice + win / 2) - win / 10) * 19 / 20);
owner.call.value(lastPaidPrice + win / 2).gas(24000)();
if (richestPlayer!=address(0)) {
payoutRound = richestRoundId;
RichestBonus(win / 10, richestPlayer);
richestPlayer.call.value(win / 10).gas(24000)();
}
}
function getPayoutRoundId() public view returns(uint) {
return payoutRound;
}
function getPrice() public view returns(uint) {
if (tokenPrice2<tokenPrice)
return tokenPrice2;
return tokenPrice;
}
function getCurrentData() public view returns (uint price, uint nextPrice, uint pool, address winner, address looser, bool canFinish, uint nextPool, uint win, uint nextWin) {
winner = tokenOwner;
looser = tokenOwner2;
price = tokenPrice2;
nextPrice = tokenPrice;
if (tokenPrice2>tokenPrice) {
winner = tokenOwner2;
looser = tokenOwner;
price = tokenPrice;
nextPrice = tokenPrice2;
}
canFinish = (tokenPrice > tokenStartPrice) && (lastBuyBlock + newRoundDelay < block.number);
pool = getPool();
if (price == tokenStartPrice) {
nextPool = pool + price;
win = 0;
} else if (price == tokenStartPrice2) {
nextPool = pool + price;
win = (pool-nextPrice.mul(50).div(110))/2;
} else {
nextPool = pool + price / 2;
win = (pool-nextPrice.mul(50).div(110))/2;
}
nextWin = (nextPool-price)/2;
}
}
{
"compilationTarget": {
"TheRichestWins.sol": "TheRichestWins"
},
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":true,"inputs":[],"name":"getPool","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"highestPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"round","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"changeContractOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"finishRound","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"richestRoundId","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentData","outputs":[{"name":"price","type":"uint256"},{"name":"nextPrice","type":"uint256"},{"name":"pool","type":"uint256"},{"name":"winner","type":"address"},{"name":"looser","type":"address"},{"name":"canFinish","type":"bool"},{"name":"nextPool","type":"uint256"},{"name":"win","type":"uint256"},{"name":"nextWin","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"delay","type":"uint256"}],"name":"changeNewRoundDelay","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"buyToken","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"flips","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBlocksToNextRound","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPayoutRoundId","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRoundId","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"richestPlayer","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"price","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"paidPrice","type":"uint256"},{"indexed":false,"name":"win","type":"uint256"},{"indexed":false,"name":"winner","type":"address"}],"name":"NewRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"win","type":"uint256"},{"indexed":false,"name":"richestPlayer","type":"address"}],"name":"RichestBonus","type":"event"}]