-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCasino.sol
145 lines (111 loc) · 4.74 KB
/
Casino.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
pragma solidity ^0.4.23;
import "./CasinoToken.sol";
import "./Table.sol";
import "./RBACWithAdmin.sol";
contract Casino is RBACWithAdmin, Ownable {
using SafeMath for uint;
event CasinoOpened();
event CasinoClosed();
string public constant ROLE_DEALER = "dealer";
modifier onlyCasinoOwner() {
checkRole(msg.sender, ROLE_ADMIN);
_;
}
modifier onlyDealer() {
checkRole(msg.sender, ROLE_DEALER);
_;
}
CasinoToken private chipTokenContract;
uint256 chipPrice;
// For simplicity the chipToken address and chipPrice cannot be changed after deploying the casino.
// We would have to recalculate the token amount and redistribute them after changing the price, since we need enough liquidity to swap tokens back into ether.
constructor (uint256 _chipPrice) public {
chipTokenContract = new CasinoToken();
chipPrice = _chipPrice;
}
function getChipSwapAddress() external view returns (address) {
return address(this);
}
function getChipTokenAddress() external view returns (address) {
return address(chipTokenContract);
}
event TableRegistered(address tableAddr);
Table[] tables;
// The owner must ensure that the contract code of Tables he deploys is correct.
// This gets called by the truffle deployment script.
function registerTable(address tableAddr) external onlyCasinoOwner {
tables.push(Table(tableAddr));
emit TableRegistered(tableAddr);
}
function getTableAddress() view external returns(address) {
return address(tables[0]); // For simplicity we assume that only one table is registered.
}
function getChipPrice() external view returns(uint256) {
return chipPrice;
}
// Invest in the casino. Tokens will be minted depending on the amount of ether you send.
// Players can buy these tokens and use them to play at our casino.
function invest() external onlyCasinoOwner payable {
require(msg.value > 0);
require(msg.value % chipPrice == 0);
require((msg.value.div(chipPrice)) % tables.length == 0); // We want to distribute tokens equally among all tables.
// Mint tokens and distribute them equally among our tables.
uint256 amount = msg.value.div(chipPrice);
chipTokenContract.mint(this, amount);
uint256 amountPerTable = amount.div(tables.length);
for (uint256 i = 0; i < tables.length; i++) {
Table table = tables[i];
chipTokenContract.transfer(address(table), amountPerTable);
}
}
// Buy chips by sending ether to the casino. No tips allowed at our casino, therefore the value must be a multiple of the chip price.
function () public payable {
require(msg.value % chipPrice == 0);
uint256 amount = msg.value.div(chipPrice);
chipTokenContract.transfer(msg.sender, amount);
}
// Swap casino chips back to ether.
function tokenFallback(address _sender, address _origin, uint256 _value, bytes _data) public returns (bool success) {
uint256 wai = _value.mul(chipPrice);
chipTokenContract.burn(_value);
_sender.transfer(wai);
return true;
}
function registerAsDealer() public {
adminAddRole(msg.sender, ROLE_DEALER);
}
// HELPER METHODS for Drizzle (to simplify UI development for the demo)
// ALL OF THE FOLLOWING METHODS SHOULD BE IMPLEMENTED IN THE UI.
// ALSO WE ASSUME THAT THERE IS ONLY ONE REGISTERED TABLE.
function becomeDealerForTable() external {
tables[0].setDealer(msg.sender);
}
function getTableDealer() view external returns (address) {
return tables[0].getDealerAddress();
}
function getPhase() view external returns (string) {
Table.Phase phase = tables[0].getPhase();
if (phase == Table.Phase.STOPPED) {
return "Table closed";
} else if (phase == Table.Phase.COMMIT) {
return "Players can place bets";
} else if (phase == Table.Phase.REVEAL) {
return "Players can reveal their numbers";
}
}
function startRound(uint256 randomNumber) external {
require(msg.sender == tables[0].getDealerAddress());
bytes32 hash = keccak256(randomNumber); // THIS SHOULD BE DONE IN THE UI.
tables[0].startRound(hash);
}
function closeRound(uint256 randomNumber) external {
require(msg.sender == tables[0].getDealerAddress());
tables[0].closeRound(randomNumber);
}
function reveal(uint256 number) external {
tables[0].reveal(number);
}
function calcHash(uint256 number) view external returns (bytes32) {
return keccak256(number); // THIS SHOULD BE DONE IN THE UI.
}
}