Created
August 26, 2024 03:44
-
-
Save edwinosky/a3cc9793dbd454c2ca64a78f4ad93433 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.26+commit.8a97fa7a.js&optimize=false&runs=200&gist=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.26; | |
import "@openzeppelin/contracts/access/Ownable.sol"; | |
import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; | |
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; | |
contract BettingContract is Ownable, ReentrancyGuard { | |
AggregatorV3Interface internal priceFeed; | |
struct Bet { | |
address user; | |
uint256 amount; | |
bool isUp; | |
uint256 timestamp; | |
bool claimed; | |
} | |
mapping(address => Bet[]) public userBets; | |
mapping(address => uint256) public userBalances; | |
uint256 public minimumBet = 0.0001 ether; | |
uint256 public roundDuration = 5 minutes; | |
uint256 public currentRoundEnd; | |
uint256 public roundNumber; | |
event BetPlaced(address indexed user, uint256 amount, bool isUp, uint256 timestamp); | |
event BetResolved(address indexed user, uint256 amountWon, bool isWinner, uint256 timestamp); | |
event Claimed(address indexed user, uint256 amount); | |
event RoundClosed(uint256 roundNumber, uint256 timestamp); | |
constructor(address _priceFeed) Ownable(msg.sender) { | |
priceFeed = AggregatorV3Interface(_priceFeed); | |
currentRoundEnd = block.timestamp + roundDuration; | |
roundNumber = 1; | |
} | |
function placeBet(bool _isUp) external payable { | |
require(block.timestamp < currentRoundEnd, "Betting is closed for this round"); | |
require(msg.value >= minimumBet, "Bet amount too low"); | |
Bet memory newBet = Bet({ | |
user: msg.sender, | |
amount: msg.value, | |
isUp: _isUp, | |
timestamp: block.timestamp, | |
claimed: false | |
}); | |
userBets[msg.sender].push(newBet); | |
emit BetPlaced(msg.sender, msg.value, _isUp, block.timestamp); | |
} | |
function resolveBet(address _user, bool _isWinner) external onlyOwner nonReentrant { | |
Bet[] storage bets = userBets[_user]; | |
require(bets.length > 0, "No bets found"); | |
uint256 totalWon = 0; | |
for (uint256 i = 0; i < bets.length; i++) { | |
if (!bets[i].claimed && bets[i].isUp == _isWinner) { | |
uint256 amountWon = bets[i].amount * 2; | |
totalWon += amountWon; | |
bets[i].claimed = true; | |
emit BetResolved(_user, amountWon, true, block.timestamp); | |
} else if (!bets[i].claimed) { | |
bets[i].claimed = true; | |
emit BetResolved(_user, 0, false, block.timestamp); | |
} | |
} | |
if (totalWon > 0) { | |
userBalances[_user] += totalWon; | |
} | |
} | |
function claim() external nonReentrant { | |
uint256 balance = userBalances[msg.sender]; | |
require(balance > 0, "No balance to claim"); | |
userBalances[msg.sender] = 0; | |
payable(msg.sender).transfer(balance); | |
emit Claimed(msg.sender, balance); | |
} | |
function getUserBets(address _user) external view returns (Bet[] memory) { | |
return userBets[_user]; | |
} | |
function getLatestPrice() public view returns (int256) { | |
( | |
, | |
int256 price, | |
, | |
, | |
) = priceFeed.latestRoundData(); | |
return price; | |
} | |
function startNewRound() external onlyOwner { | |
require(block.timestamp >= currentRoundEnd, "Current round is not yet over"); | |
currentRoundEnd = block.timestamp + roundDuration; | |
roundNumber++; | |
emit RoundClosed(roundNumber, block.timestamp); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment