Contract Name:
FootballPrediction
Contract Source Code:
File 1 of 1 : FootballPrediction
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IERC20 {
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
}
contract FootballPrediction {
address public owner;
IERC20 public token;
struct Prediction {
address user;
string predictionCode; // The prediction code like 24167
uint256 amountPaid;
}
struct Event {
uint256 eventId;
string eventName;
bool isActive;
uint256 number;
uint256 k;
mapping(address => bool) hasParticipated; // Track whether a user has participated
Prediction[] predictions; // All predictions for this event
}
uint256 public nextEventId = 1;
mapping(uint256 => Event) public events;
event PredictionSubmitted(address indexed user, uint256 eventId, string predictionCode, uint256 amountPaid);
event EventCreated(uint256 eventId, string eventName);
event EventClosed(uint256 eventId);
constructor(IERC20 _token) {
owner = msg.sender;
token = _token; // Set the token contract address
}
// Create a new event (e.g., weekly or daily matches)
function createEvent(string memory eventName,uint256 k,uint256 number) public onlyOwner {
Event storage newEvent = events[nextEventId];
newEvent.eventId = nextEventId;
newEvent.eventName = eventName;
newEvent.k = k;
newEvent.number = number;
newEvent.isActive = true;
emit EventCreated(nextEventId, eventName);
nextEventId++;
}
// Close an event (when the event has ended)
function closeEvent(uint256 eventId) public onlyOwner {
events[eventId].isActive = false;
emit EventClosed(eventId);
}
// Submit prediction for a specific event
function submitPrediction(uint256 eventId, string memory predictionCode, uint256 amount) public {
Event storage predictionEvent = events[eventId];
require(predictionEvent.isActive, "Event is not active");
require(!predictionEvent.hasParticipated[msg.sender], "User already participated in this event");
require(bytes(predictionCode).length == predictionEvent.number, "mismatch number of games");
uint256 cost = calculateCost(predictionCode, predictionEvent.number)*predictionEvent.k*10**18;
require(amount*10**18 >= cost, "Insufficient token amount");
// Transfer the token from the user to the contract
require(token.transferFrom(msg.sender, address(this), cost), "Token transfer failed");
// Record the user's prediction
predictionEvent.predictions.push(Prediction(msg.sender, predictionCode, cost));
predictionEvent.hasParticipated[msg.sender] = true; // Mark as participated
emit PredictionSubmitted(msg.sender, eventId, predictionCode, cost);
}
// Calculate the cost based on the prediction code
function calculateCost(string memory predictionCode, uint256 num) public pure returns (uint256) {
uint256 total = 1;
uint256 numTripleSelections = 0;
for (uint256 i = 0; i < num; i++) {
uint256 digit = uint256(uint8(bytes(predictionCode)[i]) - 48); // Convert character to number
require(digit >= 1 && digit <= 7, "Invalid digit in prediction");
if (digit == 7) {
numTripleSelections++;
require(numTripleSelections <= 1, "You can only select triple prediction for one match");
}
// Multiply the cost based on each match prediction
total *= getPredictionMultiplier(digit);
}
return total;
}
// Multiplier for each prediction option
function getPredictionMultiplier(uint256 predictionDigit) internal pure returns (uint256) {
if (predictionDigit == 1) return 1; // Home win
if (predictionDigit == 2) return 1; // Draw
if (predictionDigit == 3) return 1; // Away win
if (predictionDigit == 4) return 2; // Home win or draw
if (predictionDigit == 5) return 2; // Away win or draw
if (predictionDigit == 6) return 2; // Home or away win
if (predictionDigit == 7) return 3; // Home win, away win, or draw (triple selection)
return 1; // Default (should never reach here)
}
// Allow the owner to withdraw tokens from the contract
function withdraw() public onlyOwner {
uint256 balance = token.balanceOf(address(this));
require(token.transfer(owner, balance), "Withdrawal failed");
}
function getEventParticipants(uint256 eventId) public view returns (address[] memory, string[] memory, uint256[] memory) {
Event storage predictionEvent = events[eventId];
uint256 numParticipants = predictionEvent.predictions.length;
// Create arrays to store the participants' details
address[] memory participants = new address[](numParticipants);
string[] memory predictionCodes = new string[](numParticipants);
uint256[] memory amountsPaid = new uint256[](numParticipants);
// Fill the arrays with data from the predictions
for (uint256 i = 0; i < numParticipants; i++) {
Prediction storage p = predictionEvent.predictions[i];
participants[i] = p.user;
predictionCodes[i] = p.predictionCode;
amountsPaid[i] = p.amountPaid;
}
return (participants, predictionCodes, amountsPaid);
}
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function");
_;
}
}