Created
March 30, 2025 09:50
-
-
Save coderwithsense/6a6655a17d1747b0adeae5a4e852f8a6 to your computer and use it in GitHub Desktop.
Deploys new PredictionGame contracts and tracks them by creator and token pair. Core contract per market. Handles mint, burn, snapshot, claim, and progressive fee logic.
This file contains hidden or 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
// Still to be implemented |
This file contains hidden or 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.20; | |
import "./PredictionGame.sol"; | |
contract PredictionFactory { | |
address[] public allGames; | |
mapping(address => address[]) public userGames; | |
event GameCreated(address game, address creator); | |
function createPredictionGame( | |
string memory pair, | |
uint256 targetPrice, | |
uint256 expiry, | |
uint256 creatorFee | |
) external { | |
PredictionGame game = new PredictionGame( | |
msg.sender, | |
pair, | |
targetPrice, | |
expiry, | |
creatorFee | |
); | |
allGames.push(address(game)); | |
userGames[msg.sender].push(address(game)); | |
emit GameCreated(address(game), msg.sender); | |
} | |
function getAllGames() external view returns (address[] memory) { | |
return allGames; | |
} | |
function getGamesByCreator(address user) external view returns (address[] memory) { | |
return userGames[user]; | |
} | |
} |
This file contains hidden or 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.20; | |
contract PredictionGame { | |
address public creator; | |
string public pair; | |
uint256 public targetPrice; | |
uint256 public expiry; | |
uint256 public creatorFee; | |
uint256 public gameStart; | |
mapping(address => uint256) public bullTokens; | |
mapping(address => uint256) public bearTokens; | |
uint256 public totalBull; | |
uint256 public totalBear; | |
bool public isSnapshotTaken; | |
uint256 public finalPrice; | |
bool public isAbove; | |
constructor( | |
address _creator, | |
string memory _pair, | |
uint256 _target, | |
uint256 _expiry, | |
uint256 _fee | |
) { | |
creator = _creator; | |
pair = _pair; | |
targetPrice = _target; | |
expiry = _expiry; | |
creatorFee = _fee; | |
gameStart = block.timestamp; | |
} | |
function mintBull() external payable { | |
require(block.timestamp < expiry, "Game expired"); | |
require(msg.value >= 1e18, "Min 1 token"); | |
bullTokens[msg.sender] += msg.value; | |
totalBull += msg.value; | |
} | |
function mintBear() external payable { | |
require(block.timestamp < expiry, "Game expired"); | |
require(msg.value >= 1e18, "Min 1 token"); | |
bearTokens[msg.sender] += msg.value; | |
totalBear += msg.value; | |
} | |
function getBurnFee() public view returns (uint256) { | |
if (block.timestamp >= expiry) return 100; | |
uint256 timeLeft = expiry - block.timestamp; | |
uint256 totalDuration = expiry - gameStart; | |
return 100 - ((timeLeft * 100) / totalDuration); | |
} | |
function burnBull(uint256 amount) external { | |
require(bullTokens[msg.sender] >= amount, "Not enough Bull"); | |
uint256 fee = (amount * getBurnFee()) / 100; | |
uint256 refund = amount - fee; | |
bullTokens[msg.sender] -= amount; | |
totalBull -= amount; | |
payable(msg.sender).transfer(refund); | |
totalBear += (fee * 50) / 100; // 50% to bears | |
} | |
function burnBear(uint256 amount) external { | |
require(bearTokens[msg.sender] >= amount, "Not enough Bear"); | |
uint256 fee = (amount * getBurnFee()) / 100; | |
uint256 refund = amount - fee; | |
bearTokens[msg.sender] -= amount; | |
totalBear -= amount; | |
payable(msg.sender).transfer(refund); | |
totalBull += (fee * 50) / 100; // 50% to bulls | |
} | |
function takeSnapshot(uint256 _price) external { | |
require(block.timestamp >= expiry, "Too early"); | |
require(!isSnapshotTaken, "Already taken"); | |
finalPrice = _price; | |
isAbove = finalPrice > targetPrice; | |
isSnapshotTaken = true; | |
} | |
function claim() external { | |
require(isSnapshotTaken, "No snapshot"); | |
uint256 reward; | |
if (isAbove && bullTokens[msg.sender] > 0) { | |
reward = (bullTokens[msg.sender] * (totalBull + totalBear)) / totalBull; | |
reward = reward * (100 - creatorFee) / 100; | |
bullTokens[msg.sender] = 0; | |
} else if (!isAbove && bearTokens[msg.sender] > 0) { | |
reward = (bearTokens[msg.sender] * (totalBull + totalBear)) / totalBear; | |
reward = reward * (100 - creatorFee) / 100; | |
bearTokens[msg.sender] = 0; | |
} | |
require(reward > 0, "No reward"); | |
payable(msg.sender).transfer(reward); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment