S Price: $0.810309 (-5.50%)

Contract Diff Checker

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");
        _;
    }
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):