-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwithEntropy.sol
More file actions
169 lines (137 loc) · 4.72 KB
/
withEntropy.sol
File metadata and controls
169 lines (137 loc) · 4.72 KB
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@pythnetwork/entropy-sdk-solidity/IEntropy.sol";
import "@pythnetwork/entropy-sdk-solidity/IEntropyConsumer.sol";
library CoinFlipErrors {
error IncorrectSender();
error InsufficientFee();
}
contract PythCoinFlip is IEntropyConsumer {
struct FlipDetails {
Bet bet;
CoinTossBet coinTossBet;
}
struct CoinTossBet {
bool face;
bool rolled;
}
mapping(uint256 => CoinTossBet) public coinTossBets;
struct Bet {
bool resolved;
address user;
uint256 id;
uint256 blockTime;
bool betStatus;
}
event PlaceBet(uint256 id, address indexed user, bool face);
event Roll(uint256 id, address indexed user, bool face, bool rolled);
/// @notice Maps bets IDs to Bet information.
mapping(uint256 => Bet) public bets;
/// @notice Maps users addrejsses to bets IDs
mapping(address => uint256[]) internal _userBets;
event FlipRequest(uint64 sequenceNumber);
event FlipResult(uint64 sequenceNumber, bool isHeads);
IEntropy private entropy;
address public entropyProvider;
receive() external payable {}
constructor(address _entropy) {
entropy = IEntropy(_entropy);
}
function getProvider() external view returns (address) {
address p = entropy.getDefaultProvider();
return p;
}
function getFlipFee() public view returns (uint256 fee) {
fee = entropy.getFee(entropyProvider);
}
function entropyCallback(
uint64 sequenceNumber,
address,
bytes32 randomNumber
) internal override {
uint256 _s = uint256(sequenceNumber);
CoinTossBet storage coinTossBet = coinTossBets[_s];
Bet storage bet = bets[_s];
bool rolled = uint256(randomNumber) % 2 == 0;
coinTossBet.rolled = rolled;
if (rolled == coinTossBet.face) {
bet.resolved = true;
bet.betStatus = true;
emit Roll(bet.id, bet.user, coinTossBet.face, rolled);
} else {
bet.resolved = true;
bet.betStatus = false;
emit Roll(bet.id, bet.user, coinTossBet.face, rolled);
}
emit Roll(bet.id, bet.user, coinTossBet.face, rolled);
emit FlipResult(sequenceNumber, uint256(randomNumber) % 2 == 0);
}
function getEntropy() internal view override returns (address) {
return address(entropy);
}
function flipWithPyth(
bool face,
bytes32 userRandomNumber
) external payable {
address provider = entropy.getDefaultProvider();
uint256 fee = entropy.getFee(provider);
if (msg.value < fee) {
revert CoinFlipErrors.InsufficientFee();
}
uint64 sequenceNumber = entropy.requestWithCallback{value: fee}(
provider,
userRandomNumber
);
uint256 _s = uint256(sequenceNumber);
emit FlipRequest(sequenceNumber);
Bet memory newBet = Bet(false, msg.sender, _s, block.timestamp, false);
_userBets[msg.sender].push(_s);
bets[_s] = newBet;
coinTossBets[newBet.id].face = face;
emit PlaceBet(newBet.id, newBet.user, face);
}
function getBetData(uint256 id) public view returns (Bet memory betData) {
Bet storage data = bets[id];
return data;
}
function getBetStatus(uint256 id) public view returns (bool status) {
Bet storage data = bets[id];
return data.betStatus;
}
function _getLastUserBets(
address user,
uint256 dataLength
) internal view returns (Bet[] memory) {
uint256[] memory userBetsIds = _userBets[user];
uint256 betsLength = userBetsIds.length;
if (betsLength < dataLength) {
dataLength = betsLength;
}
Bet[] memory userBets = new Bet[](dataLength);
if (dataLength != 0) {
uint256 userBetsIndex;
for (uint256 i = betsLength; i > betsLength - dataLength; i--) {
userBets[userBetsIndex] = bets[userBetsIds[i - 1]];
userBetsIndex++;
}
}
return userBets;
}
/// @return A list of Coin Toss bet.
function getUserBet(
address user,
uint256 dataLength
) external view returns (FlipDetails[] memory) {
Bet[] memory lastBets = _getLastUserBets(user, dataLength);
FlipDetails[] memory lastCoinTossBets = new FlipDetails[](
lastBets.length
);
for (uint256 i; i < lastBets.length; i++) {
lastCoinTossBets[i] = FlipDetails(
lastBets[i],
coinTossBets[lastBets[i].id]
);
}
return lastCoinTossBets;
}
}