pragma solidity ^0.5.11;
//
// * whitebetting.com - the whitest football betting game based on ethereum blockchain
// on 2019-09-24
//
contract WhiteBetting {
address payable public owner;
// Game information
struct GameInfo {
// game start time
uint256 timestamp;
// game odds
uint32 odd_homeTeam;
uint32 odd_drawTeam;
uint32 odd_awayTeam;
uint32 odd_over;
uint32 odd_under;
uint32 odd_homeTeamAndDraw;
uint32 odd_homeAndAwayTeam;
uint32 odd_awayTeamAndDraw;
// Checking the game status
uint8 open_status;
// Checking whether winning were paid
bool isDone;
}
mapping(uint64 => GameInfo) public gameList;
// Player betting infomation
struct BetFixture {
address payable player;
uint256 stake;
uint32 odd;
// betting type
uint16 selectedTeam;
}
mapping(uint64 => BetFixture[]) public betList;
// Events that are issued to make statistic recovery easier
event Success(uint256 odd);
event Deposit(address sender, uint256 eth);
event Withdraw(address receiver, uint256 eth);
event NewStake(address player, uint64 fixtureId, uint16 selectedTeam, uint256 stake, uint256 odd );
event SetGame(uint64 _fixtureId, uint256 _timestamp, uint32 _odd_homeTeam, uint32 _odd_drawTeam, uint32 _odd_awayTeam, uint32 _odd_over, uint32 _odd_under, uint32 _odd_homeTeamAndDraw, uint32 _odd_homeAndAwayTeam , uint32 _odd_awayTeamAndDraw, uint8 _open_status);
event ChangeOdd (uint64 _fixtureId, uint32 _odd_homeTeam, uint32 _odd_drawTeam, uint32 _odd_awayTeam, uint32 _odd_over, uint32 _odd_under, uint32 _odd_homeTeamAndDraw, uint32 _odd_homeAndAwayTeam , uint32 _odd_awayTeamAndDraw);
event GivePrizeMoney(uint64 _fixtureId, uint8 _homeDrawAway, uint8 _overUnder);
// Constructor
constructor() public {
owner = msg.sender;
}
// Change the game status
function setOpenStatus(uint64 _fixtureId, uint8 _open_status) external onlyOwner {
gameList[_fixtureId].open_status = _open_status;
}
// Refresh the game odd
function changeOdd (uint64 _fixtureId, uint32 _odd_homeTeam, uint32 _odd_drawTeam, uint32 _odd_awayTeam, uint32 _odd_over, uint32 _odd_under, uint32 _odd_homeTeamAndDraw, uint32 _odd_homeAndAwayTeam , uint32 _odd_awayTeamAndDraw ) external onlyOwner {
gameList[_fixtureId].odd_homeTeam = _odd_homeTeam;
gameList[_fixtureId].odd_drawTeam = _odd_drawTeam;
gameList[_fixtureId].odd_awayTeam = _odd_awayTeam;
gameList[_fixtureId].odd_over = _odd_over;
gameList[_fixtureId].odd_under = _odd_under;
gameList[_fixtureId].odd_homeTeamAndDraw = _odd_homeTeamAndDraw;
gameList[_fixtureId].odd_homeAndAwayTeam = _odd_homeAndAwayTeam;
gameList[_fixtureId].odd_awayTeamAndDraw = _odd_awayTeamAndDraw;
emit ChangeOdd (_fixtureId, _odd_homeTeam, _odd_drawTeam, _odd_awayTeam, _odd_over, _odd_under, _odd_homeTeamAndDraw, _odd_homeAndAwayTeam , _odd_awayTeamAndDraw);
}
// Save the game information
function setGameInfo (uint64 _fixtureId, uint256 _timestamp, uint32 _odd_homeTeam, uint32 _odd_drawTeam, uint32 _odd_awayTeam, uint32 _odd_over, uint32 _odd_under, uint32 _odd_homeTeamAndDraw, uint32 _odd_homeAndAwayTeam , uint32 _odd_awayTeamAndDraw, uint8 _open_status ) external onlyOwner {
gameList[_fixtureId].timestamp = _timestamp;
gameList[_fixtureId].odd_homeTeam = _odd_homeTeam;
gameList[_fixtureId].odd_drawTeam = _odd_drawTeam;
gameList[_fixtureId].odd_awayTeam = _odd_awayTeam;
gameList[_fixtureId].odd_over = _odd_over;
gameList[_fixtureId].odd_under = _odd_under;
gameList[_fixtureId].odd_homeTeamAndDraw = _odd_homeTeamAndDraw;
gameList[_fixtureId].odd_homeAndAwayTeam = _odd_homeAndAwayTeam;
gameList[_fixtureId].odd_awayTeamAndDraw = _odd_awayTeamAndDraw;
gameList[_fixtureId].open_status = _open_status;
gameList[_fixtureId].isDone = false;
emit SetGame(_fixtureId, _timestamp, _odd_homeTeam, _odd_drawTeam, _odd_awayTeam, _odd_over, _odd_under, _odd_homeTeamAndDraw, _odd_homeAndAwayTeam , _odd_awayTeamAndDraw, _open_status);
}
// Player make a bet
function placeBet(uint64 _fixtureId, uint16 _selectedTeam, uint32 _odd) external payable {
uint stake = msg.value;
// Minium amount to bet is 0.001 ether
require(stake >= .001 ether);
// Check whether odds is valid
require(_odd != 0 );
// Compare to match mainnet odds with was submitted odds by betting type
if (_selectedTeam == 1 ) {
require(gameList[_fixtureId].odd_homeTeam == _odd);
} else if ( _selectedTeam == 2) {
require(gameList[_fixtureId].odd_drawTeam == _odd);
} else if ( _selectedTeam == 3) {
require(gameList[_fixtureId].odd_awayTeam == _odd);
} else if ( _selectedTeam == 4) {
require(gameList[_fixtureId].odd_over == _odd);
} else if ( _selectedTeam == 5) {
require(gameList[_fixtureId].odd_under == _odd);
} else if ( _selectedTeam == 6) {
require(gameList[_fixtureId].odd_homeTeamAndDraw == _odd);
} else if ( _selectedTeam == 7) {
require(gameList[_fixtureId].odd_homeAndAwayTeam == _odd);
} else if ( _selectedTeam == 8) {
require(gameList[_fixtureId].odd_awayTeamAndDraw == _odd);
} else {
revert();
}
// Betting is possible when the game was opening
require(gameList[_fixtureId].open_status == 3);
// Betting is possible only 10 min. ago
require( now < ( gameList[_fixtureId].timestamp - 10 minutes ) );
// Save the betting information
betList[_fixtureId].push(BetFixture( msg.sender, stake, _odd, _selectedTeam));
emit NewStake(msg.sender, _fixtureId, _selectedTeam, stake, _odd );
}
// Give prize money by the game result
function givePrizeMoney(uint64 _fixtureId, uint8 _homeDrawAway, uint8 _overUnder) external onlyOwner payable {
// Check the game status whether is opening
require(gameList[_fixtureId].open_status == 3);
// Check if it has ever compensated
require(gameList[_fixtureId].isDone == false);
// Check if it has any player who betted
require(betList[_fixtureId][0].player != address(0) );
// Give the prize money!
for (uint i= 0 ; i < betList[_fixtureId].length; i++){
uint16 selectedTeam = betList[_fixtureId][i].selectedTeam;
uint256 returnEth = (betList[_fixtureId][i].stake * betList[_fixtureId][i].odd) / 1000 ;
if ( (selectedTeam == 1 && _homeDrawAway == 1)
|| (selectedTeam == 2 && _homeDrawAway == 2)
|| (selectedTeam == 3 && _homeDrawAway == 3)
|| (selectedTeam == 4 && _overUnder == 1)
|| (selectedTeam == 5 && _overUnder == 2)
|| (selectedTeam == 6 && ( _homeDrawAway == 1 || _homeDrawAway == 2) )
|| (selectedTeam == 7 && ( _homeDrawAway == 1 || _homeDrawAway == 3) )
|| (selectedTeam == 8 && ( _homeDrawAway == 3 || _homeDrawAway == 2) )
){
betList[_fixtureId][i].player.transfer(returnEth);
}
}
// Change the game status.
gameList[_fixtureId].open_status = 5;
// It was paid.
gameList[_fixtureId].isDone = true; // 보상을 마쳤으므로 true로 변경.
emit GivePrizeMoney( _fixtureId, _homeDrawAway, _overUnder);
}
// Standard modifier on methods invokable only by contract owner.
modifier onlyOwner {
require (msg.sender == owner, "OnlyOwner methods called by non-owner.");
_;
}
// Get this balance of CA
function getBalance() external view returns(uint){
return address(this).balance;
}
// Deposit from owner to CA
function deposit(uint256 _eth) external payable{
emit Deposit(msg.sender, _eth);
}
// Change Owner
function changeOwner(address payable _newOwner ) external onlyOwner {
owner = _newOwner;
}
// Fallback function
function () external payable{
owner.transfer(msg.value);
}
// Withdraw from CA to owner
function withdraw(uint256 _amount) external payable onlyOwner {
require(_amount > 0 && _amount <= address(this).balance );
owner.transfer(_amount);
emit Withdraw(owner, _amount);
}
}
{
"compilationTarget": {
"WhiteBetting.sol": "WhiteBetting"
},
"evmVersion": "petersburg",
"libraries": {},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"constant":false,"inputs":[{"internalType":"uint64","name":"_fixtureId","type":"uint64"},{"internalType":"uint32","name":"_odd_homeTeam","type":"uint32"},{"internalType":"uint32","name":"_odd_drawTeam","type":"uint32"},{"internalType":"uint32","name":"_odd_awayTeam","type":"uint32"},{"internalType":"uint32","name":"_odd_over","type":"uint32"},{"internalType":"uint32","name":"_odd_under","type":"uint32"},{"internalType":"uint32","name":"_odd_homeTeamAndDraw","type":"uint32"},{"internalType":"uint32","name":"_odd_homeAndAwayTeam","type":"uint32"},{"internalType":"uint32","name":"_odd_awayTeamAndDraw","type":"uint32"}],"name":"changeOdd","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint64","name":"_fixtureId","type":"uint64"},{"internalType":"uint16","name":"_selectedTeam","type":"uint16"},{"internalType":"uint32","name":"_odd","type":"uint32"}],"name":"placeBet","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"betList","outputs":[{"internalType":"address payable","name":"player","type":"address"},{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint32","name":"odd","type":"uint32"},{"internalType":"uint16","name":"selectedTeam","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"gameList","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint32","name":"odd_homeTeam","type":"uint32"},{"internalType":"uint32","name":"odd_drawTeam","type":"uint32"},{"internalType":"uint32","name":"odd_awayTeam","type":"uint32"},{"internalType":"uint32","name":"odd_over","type":"uint32"},{"internalType":"uint32","name":"odd_under","type":"uint32"},{"internalType":"uint32","name":"odd_homeTeamAndDraw","type":"uint32"},{"internalType":"uint32","name":"odd_homeAndAwayTeam","type":"uint32"},{"internalType":"uint32","name":"odd_awayTeamAndDraw","type":"uint32"},{"internalType":"uint8","name":"open_status","type":"uint8"},{"internalType":"bool","name":"isDone","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint64","name":"_fixtureId","type":"uint64"},{"internalType":"uint8","name":"_homeDrawAway","type":"uint8"},{"internalType":"uint8","name":"_overUnder","type":"uint8"}],"name":"givePrizeMoney","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint64","name":"_fixtureId","type":"uint64"},{"internalType":"uint8","name":"_open_status","type":"uint8"}],"name":"setOpenStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable","name":"_newOwner","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_eth","type":"uint256"}],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint64","name":"_fixtureId","type":"uint64"},{"internalType":"uint256","name":"_timestamp","type":"uint256"},{"internalType":"uint32","name":"_odd_homeTeam","type":"uint32"},{"internalType":"uint32","name":"_odd_drawTeam","type":"uint32"},{"internalType":"uint32","name":"_odd_awayTeam","type":"uint32"},{"internalType":"uint32","name":"_odd_over","type":"uint32"},{"internalType":"uint32","name":"_odd_under","type":"uint32"},{"internalType":"uint32","name":"_odd_homeTeamAndDraw","type":"uint32"},{"internalType":"uint32","name":"_odd_homeAndAwayTeam","type":"uint32"},{"internalType":"uint32","name":"_odd_awayTeamAndDraw","type":"uint32"},{"internalType":"uint8","name":"_open_status","type":"uint8"}],"name":"setGameInfo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"odd","type":"uint256"}],"name":"Success","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"eth","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"eth","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint64","name":"fixtureId","type":"uint64"},{"indexed":false,"internalType":"uint16","name":"selectedTeam","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"stake","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"odd","type":"uint256"}],"name":"NewStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"_fixtureId","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"_odd_homeTeam","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_drawTeam","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_awayTeam","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_over","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_under","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_homeTeamAndDraw","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_homeAndAwayTeam","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_awayTeamAndDraw","type":"uint32"},{"indexed":false,"internalType":"uint8","name":"_open_status","type":"uint8"}],"name":"SetGame","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"_fixtureId","type":"uint64"},{"indexed":false,"internalType":"uint32","name":"_odd_homeTeam","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_drawTeam","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_awayTeam","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_over","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_under","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_homeTeamAndDraw","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_homeAndAwayTeam","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_odd_awayTeamAndDraw","type":"uint32"}],"name":"ChangeOdd","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"_fixtureId","type":"uint64"},{"indexed":false,"internalType":"uint8","name":"_homeDrawAway","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"_overUnder","type":"uint8"}],"name":"GivePrizeMoney","type":"event"}]