-
Notifications
You must be signed in to change notification settings - Fork 0
/
Bet.sol
70 lines (64 loc) · 2.53 KB
/
Bet.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
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract myBet {
mapping(uint => mapping(uint => uint)) public choiceBets;
mapping(uint => mapping(address => uint)) public userBets;
mapping(uint => mapping(address => bool)) public userWithdrawn;
mapping(uint => address[]) takers;
struct Bet {
string terms;
uint amount;
string options;
address oracle;
uint outcome;
uint totalPool;
address paymentToken;
}
Bet[] public bets;
function createBet(string memory terms, uint amount, string memory options, address paymentToken) public {
bets.push(Bet({
terms: terms,
amount: amount,
options: options,
oracle: msg.sender,
outcome: 0,
totalPool: 0,
paymentToken: paymentToken
}));
}
function placeBet(uint betIndex, uint option) public payable {
Bet memory currentBet = bets[betIndex];
if(currentBet.paymentToken == address(0)) {
require(msg.value == currentBet.amount, "Must meet the bet requirement");
} else {
IERC20(currentBet.paymentToken).allowance(msg.sender, address(this)) >= currentBet.amount;
IERC20(currentBet.paymentToken).transferFrom(msg.sender, address(this), currentBet.amount);
}
require(option > 0, "You must use 1 based indexes for choosing an option");
require(currentBet.outcome == 0, "Cannot bet on a done game");
userBets[betIndex][msg.sender] = option;
choiceBets[betIndex][option]++;
takers[betIndex].push(msg.sender);
bets[betIndex].totalPool += currentBet.amount;
}
function resolveBet(uint betIndex, uint outcome) public {
Bet memory currentBet = bets[betIndex];
require(currentBet.oracle == msg.sender, "You don't have permission to resolve this bet");
require(outcome > 0, "Use 1 based indexes for outcome");
bets[betIndex].outcome = outcome;
}
function withdraw(uint betIndex) public {
Bet memory currentBet = bets[betIndex];
require(currentBet.outcome > 0, "Bet is not resolved");
require(userBets[betIndex][msg.sender] == currentBet.outcome, "You didn't select the correct answer");
require(userWithdrawn[betIndex][msg.sender] == false, "You've already withdrawn");
userWithdrawn[betIndex][msg.sender] = true;
uint reward = currentBet.totalPool / choiceBets[betIndex][currentBet.outcome];
if(currentBet.paymentToken == address(0x0)) {
payable(address(msg.sender)).transfer(reward);
} else {
IERC20(currentBet.paymentToken).transfer(msg.sender, reward);
}
}
}