编译器
0.8.21+commit.d9974bed
文件 1 的 16:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 16:AggregatorV3Interface.sol
pragma solidity ^0.8.0;
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
function getRoundData(
uint80 _roundId
) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
function latestRoundData()
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}
文件 3 的 16:AutomateReady.sol
pragma solidity ^0.8.14;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./Types.sol";
abstract contract AutomateReady {
IAutomate public immutable automate;
address public immutable dedicatedMsgSender;
address private immutable feeCollector;
address internal constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address private constant OPS_PROXY_FACTORY =
0xC815dB16D4be6ddf2685C201937905aBf338F5D7;
modifier onlyDedicatedMsgSender() {
require(msg.sender == dedicatedMsgSender, "Only dedicated msg.sender");
_;
}
constructor(address _automate, address _taskCreator) {
automate = IAutomate(_automate);
IGelato gelato = IGelato(IAutomate(_automate).gelato());
feeCollector = gelato.feeCollector();
(dedicatedMsgSender, ) = IOpsProxyFactory(OPS_PROXY_FACTORY).getProxyOf(
_taskCreator
);
}
function _transfer(uint256 _fee, address _feeToken) internal {
if (_feeToken == ETH) {
(bool success, ) = feeCollector.call{value: _fee}("");
require(success, "_transfer: ETH transfer failed");
} else {
SafeERC20.safeTransfer(IERC20(_feeToken), feeCollector, _fee);
}
}
function _getFeeDetails()
internal
view
returns (uint256 fee, address feeToken)
{
(fee, feeToken) = automate.getFeeDetails();
}
}
文件 4 的 16:AutomateTaskCreator.sol
pragma solidity ^0.8.14;
import "./AutomateReady.sol";
abstract contract AutomateTaskCreator is AutomateReady {
using SafeERC20 for IERC20;
address public immutable fundsOwner;
ITaskTreasuryUpgradable public immutable taskTreasury;
constructor(
address _automate,
address _fundsOwner
) AutomateReady(_automate, address(this)) {
fundsOwner = _fundsOwner;
taskTreasury = automate.taskTreasury();
}
function withdrawFunds(uint256 _amount) external {
require(
msg.sender == fundsOwner,
"Only funds owner can withdraw funds"
);
taskTreasury.withdrawFunds(
payable(fundsOwner),
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE,
_amount
);
}
function _depositFunds(uint256 _amount, address _token) internal {
uint256 ethValue = _token == ETH ? _amount : 0;
taskTreasury.depositFunds{value: ethValue}(
address(this),
_token,
_amount
);
}
function _createTask(
address _execAddress,
bytes memory _execDataOrSelector,
ModuleData memory _moduleData,
address _feeToken
) internal returns (bytes32) {
return
automate.createTask(
_execAddress,
_execDataOrSelector,
_moduleData,
_feeToken
);
}
function _cancelTask(bytes32 _taskId) internal {
automate.cancelTask(_taskId);
}
function _resolverModuleArg(
address _resolverAddress,
bytes memory _resolverData
) internal pure returns (bytes memory) {
return abi.encode(_resolverAddress, _resolverData);
}
function _timeModuleArg(
uint256 _startTime,
uint256 _interval
) internal pure returns (bytes memory) {
return abi.encode(uint128(_startTime), uint128(_interval));
}
function _proxyModuleArg() internal pure returns (bytes memory) {
return bytes("");
}
function _singleExecModuleArg() internal pure returns (bytes memory) {
return bytes("");
}
}
文件 5 的 16:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 6 的 16:EnumerableSet.sol
pragma solidity ^0.8.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping(bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastValue = set._values[lastIndex];
set._values[toDeleteIndex] = lastValue;
set._indexes[lastValue] = valueIndex;
}
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
assembly {
result := store
}
return result;
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
文件 7 的 16:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 8 的 16:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 9 的 16:IUniswapV2Factory.sol
pragma solidity >=0.8.0;
interface IUniswapV2Factory {
event PairCreated(
address indexed token0,
address indexed token1,
address pair,
uint
);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function getPair(address tokenA, address tokenB)
external
view
returns (address pair);
function allPairs(uint) external view returns (address pair);
function allPairsLength() external view returns (uint);
function createPair(address tokenA, address tokenB)
external
returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
}
文件 10 的 16:IUniswapV2Router.sol
pragma solidity >=0.8.0;
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
)
external
payable
returns (uint amountToken, uint amountETH, uint liquidity);
function quote(
uint amountA,
uint reserveA,
uint reserveB
) external pure returns (uint amountB);
function getAmountsOut(
uint256 amountIn,
address[] memory path
) external view returns (uint256[] memory amounts);
}
文件 11 的 16:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 12 的 16:PredictionMarket.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./RefProgramCodeGenerator.sol";
import "./Gelato/AutomateTaskCreator.sol";
import "./IUniswapV2Factory.sol";
import "./IUniswapV2Router.sol";
interface IERC20Balance {
function decimals() external view returns (uint8);
}
interface IPredictionFactory {
function addEthPayout(uint256 value) external;
function owner() external view returns (address);
}
interface INonce {
function generatedNonce(
address user,
uint256 roundID
) external pure returns (uint256);
}
contract PredictionMarket is Ownable, ReentrancyGuard, AutomateTaskCreator {
using EnumerableSet for EnumerableSet.UintSet;
using EnumerableSet for EnumerableSet.AddressSet;
event BetBear(address indexed user, uint256 indexed round, uint256 amount);
event BetBull(address indexed user, uint256 indexed round, uint256 amount);
event BullClaimed(
address indexed user,
uint256 roundId,
uint256 amountClaimed
);
event BearClaimed(
address indexed user,
uint256 roundId,
uint256 amountClaimed
);
event CounterTaskCreated(bytes32 taskId);
receive() external payable {}
address public predictionFactory;
AggregatorV3Interface internal dataFeed;
bytes32 public taskId;
address private _refProgramCodeGenerator;
bool public isRefProgramOpen;
mapping(address => EnumerableSet.UintSet) private _userActivatedCodes;
mapping(address => EnumerableSet.UintSet) private _userGeneratedCodes;
mapping(uint256 => EnumerableSet.AddressSet) private _CodeClaimedAddresses;
uint256 public totalCodesUsed;
address public router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
address public treasuryWallet;
address public token;
address public pair;
uint256 public roundID;
uint256 public roundPeriod = 30 minutes;
uint256 public bufferTime = 40;
uint256 public minimumBet = 0.01 ether;
uint256 public poolFee = 500;
bool public isStopped;
struct Round {
uint256 startTimestamp;
uint256 expireTimestamp;
uint256 openPrice;
uint256 closePrice;
uint256 bearBetsAmount;
uint256 bullBetsAmount;
uint256 totalEthBets;
bool roundClose;
}
mapping(uint256 => Round) private rounds;
struct UserEntries {
uint256 bullEntries;
uint256 bearEntries;
uint256 totalEthBetted;
uint256 totalEthWon;
bool bullClaimed;
bool bearClaimed;
}
mapping(address => mapping(uint256 => UserEntries)) private userEntries;
mapping(address => EnumerableSet.UintSet) private _userBetRounds;
uint256 public totalEthPayoutsMade;
constructor(
address _token,
address _automate,
address _fundsOwner
) payable AutomateTaskCreator(_automate, _fundsOwner) {
require(hasEthLiquidity(_token), "Pair has no liquidity");
dataFeed = AggregatorV3Interface(
0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
);
token = _token;
pair = getPair(_token);
treasuryWallet = _fundsOwner;
predictionFactory = msg.sender;
require(pair != address(0), "No pair found");
depositFunds(msg.value, 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
createTask();
}
function getUserActivatedCodes(
address user
) public view returns (uint256[] memory) {
return _userActivatedCodes[user].values();
}
function getUserGeneratedCodes(
address user
) public view returns (uint256[] memory) {
return _userGeneratedCodes[user].values();
}
function getCodesUsedAddresses(
uint256 code
) public view returns (address[] memory) {
return _CodeClaimedAddresses[code].values();
}
function getCodesUsedCount(uint256 code) public view returns (uint256) {
return _CodeClaimedAddresses[code].length();
}
function getUserGeneratedCodesCount(
address user
) public view returns (uint256) {
return _userGeneratedCodes[user].length();
}
function getUserActivatedCodesCount(
address user
) public view returns (uint256) {
return _userActivatedCodes[user].length();
}
function isCodeUsable(
uint256 code,
address user
) public view returns (bool) {
address sharer = _CodeClaimedAddresses[code].at(0);
if (_CodeClaimedAddresses[code].length() != 1 || user == sharer) {
return false;
}
if (sharer == address(0)) {
return false;
}
return true;
}
function updateRefProgrammStatus() public onlyOwner {
if (!isRefProgramOpen && _refProgramCodeGenerator == address(0)) {
RefProgramCodeGenerator refProgramCodeGenerator = new RefProgramCodeGenerator();
_refProgramCodeGenerator = address(refProgramCodeGenerator);
}
isRefProgramOpen = !isRefProgramOpen;
}
function setPoolFee(uint256 _newFee) external onlyOwner {
require(_newFee <= 2_000, "Fee too high");
poolFee = _newFee;
}
function setRoundPeriod(uint256 _newRoundPeriod) public onlyOwner {
roundPeriod = _newRoundPeriod;
}
function depositFunds(uint256 _amount, address _token) public payable {
uint256 ethValue = _token == ETH ? _amount : 0;
taskTreasury.depositFunds{value: ethValue}(
address(this),
_token,
_amount
);
}
function createTask() public {
require(taskId == bytes32(""), "Already started task");
ModuleData memory moduleData = ModuleData({
modules: new Module[](2),
args: new bytes[](2)
});
moduleData.modules[0] = Module.RESOLVER;
moduleData.modules[1] = Module.PROXY;
moduleData.args[0] = _resolverModuleArg(
address(this),
abi.encodeCall(this.checker, ())
);
moduleData.args[1] = _proxyModuleArg();
bytes32 id = _createTask(
address(this),
abi.encode(this.startNewRound.selector),
moduleData,
address(0)
);
taskId = id;
emit CounterTaskCreated(id);
}
function getRoundInfo(
uint256 roundId
)
public
view
returns (
uint256 startTimestamp,
uint256 expireTimestamp,
uint256 openPrice,
uint256 closePrice,
uint256 bearBetsAmount,
uint256 bullBetsAmount,
uint256 totalEthBets,
bool roundClose
)
{
Round storage round = rounds[roundId];
return (
round.startTimestamp,
round.expireTimestamp,
round.openPrice,
round.closePrice,
round.bearBetsAmount,
round.bullBetsAmount,
round.totalEthBets,
round.roundClose
);
}
function getUserEntries(
address user,
uint256 roundId
)
public
view
returns (
uint256 bullEntries,
uint256 bearEntries,
uint256 totalEthBetted,
uint256 totalEthWon,
bool bullClaimed,
bool bearClaimed
)
{
UserEntries storage entries = userEntries[user][roundId];
return (
entries.bullEntries,
entries.bearEntries,
entries.totalEthBetted,
entries.totalEthWon,
entries.bullClaimed,
entries.bearClaimed
);
}
function getUserRounds(
address user
) public view returns (uint256[] memory) {
return _userBetRounds[user].values();
}
function getTokenPriceEth() internal view returns (uint256) {
uint256 totalEth = IERC20(IUniswapV2Router01(router).WETH()).balanceOf(
pair
) * 10 ** IERC20Balance(token).decimals();
uint256 tokenBalance = IERC20(token).balanceOf(pair);
return totalEth / tokenBalance;
}
function getChainlinkDataFeedLatestAnswer() internal view returns (int) {
(
,
int answer,
,
,
) = dataFeed.latestRoundData();
return answer;
}
function getTokenPriceUSD() public view returns (uint256) {
uint256 ethPrice = uint256(getChainlinkDataFeedLatestAnswer());
uint256 tokenEthPrice = getTokenPriceEth();
return ethPrice * tokenEthPrice;
}
function getPair(address _token) internal view returns (address) {
address _pair;
address factory = IUniswapV2Router01(router).factory();
address wEth = IUniswapV2Router01(router).WETH();
_pair = IUniswapV2Factory(factory).getPair(_token, wEth);
return _pair;
}
function checker()
public
view
returns (bool canExec, bytes memory execPayload)
{
Round storage roundData = rounds[roundID];
if (roundID == 0 && roundData.startTimestamp == 0) {
canExec = true;
} else if (!isStopped) {
canExec = roundData.expireTimestamp < block.timestamp;
}
execPayload = abi.encodeCall(this.startNewRound, ());
}
function stop() public {
require(
msg.sender == owner() ||
msg.sender == IPredictionFactory(predictionFactory).owner()
);
isStopped = !isStopped;
}
function newRoundStartable() public view returns (bool canExec) {
Round storage roundData = rounds[roundID];
if (roundID == 0 && roundData.startTimestamp == 0) {
canExec = true;
} else if (!isStopped) {
canExec = roundData.expireTimestamp < block.timestamp;
}
}
function startNewRound() public {
require(newRoundStartable(), "Round not ended");
Round storage currentRound = rounds[roundID];
Round storage nextRound = rounds[roundID + 1];
if (roundID == 0 && currentRound.startTimestamp == 0) {
currentRound.startTimestamp = block.timestamp;
currentRound.expireTimestamp = block.timestamp + roundPeriod;
currentRound.openPrice = getTokenPriceUSD();
} else {
currentRound.closePrice = getTokenPriceUSD();
currentRound.roundClose = true;
nextRound.startTimestamp = block.timestamp;
nextRound.expireTimestamp = block.timestamp + roundPeriod;
nextRound.openPrice = getTokenPriceUSD();
roundID++;
}
}
function roundResult(uint256 _roundID) public view returns (bool isBull) {
Round storage roundData = rounds[_roundID];
return (roundData.openPrice < roundData.closePrice);
}
function isEven(uint256 _roundID) public view returns (bool) {
Round storage roundData = rounds[_roundID];
return (roundData.openPrice == roundData.closePrice);
}
function bettingOpen() public view returns (bool) {
Round storage roundData = rounds[roundID];
return roundData.expireTimestamp - bufferTime > block.timestamp;
}
function enterBull(uint256 amount, uint256 refCode) public payable {
require(amount == msg.value, "Amount incorrect");
require(msg.value >= minimumBet, "Bet more");
UserEntries storage userData = userEntries[msg.sender][roundID + 1];
require(
userData.bearEntries == 0 && userData.bullEntries == 0,
"Already entered"
);
bool canBet = bettingOpen();
require(canBet);
if (isRefProgramOpen) {
uint256 userNonce = INonce(_refProgramCodeGenerator).generatedNonce(
_msgSender(),
roundID
) % 9999999;
_userGeneratedCodes[msg.sender].add(userNonce);
_userActivatedCodes[msg.sender].add(userNonce);
_CodeClaimedAddresses[userNonce].add(msg.sender);
totalCodesUsed++;
if (refCode != 0) {
require(
isCodeUsable(refCode, msg.sender),
"Code does not exist or used"
);
address sharer = _CodeClaimedAddresses[refCode].at(0);
uint256 newCode = refCode % 9999;
_userActivatedCodes[sharer].add(newCode);
_userActivatedCodes[msg.sender].add(refCode);
_CodeClaimedAddresses[refCode].add(msg.sender);
totalCodesUsed++;
}
}
Round storage roundData = rounds[roundID + 1];
uint256 fee = (amount * poolFee) / 10_000;
bool success;
(success, ) = address(treasuryWallet).call{value: fee}("");
amount -= fee;
roundData.bullBetsAmount += amount;
roundData.totalEthBets += amount;
userData.bullEntries += amount;
userData.totalEthBetted += amount;
_userBetRounds[msg.sender].add(roundID + 1);
emit BetBull(msg.sender, roundID + 1, amount);
}
function enterBear(uint256 amount, uint256 refCode) public payable {
require(amount == msg.value, "Amount incorrect");
require(msg.value >= minimumBet, "Bet more");
UserEntries storage userData = userEntries[msg.sender][roundID + 1];
require(
userData.bullEntries == 0 || userData.bearEntries == 0,
"Already entered"
);
bool canBet = bettingOpen();
require(canBet);
if (isRefProgramOpen) {
uint256 userNonce = INonce(_refProgramCodeGenerator).generatedNonce(
_msgSender(),
roundID
) % 9999999;
_userGeneratedCodes[msg.sender].add(userNonce);
_userActivatedCodes[msg.sender].add(userNonce);
_CodeClaimedAddresses[userNonce].add(msg.sender);
totalCodesUsed++;
if (refCode != 0) {
require(
isCodeUsable(refCode, msg.sender),
"Code does not exist or used"
);
address sharer = _CodeClaimedAddresses[refCode].at(0);
uint256 newCode = refCode % 9999;
_userActivatedCodes[sharer].add(newCode);
_userActivatedCodes[msg.sender].add(refCode);
_CodeClaimedAddresses[refCode].add(msg.sender);
totalCodesUsed++;
}
}
Round storage roundData = rounds[roundID + 1];
uint256 fee = (amount * poolFee) / 10_000;
bool success;
(success, ) = address(treasuryWallet).call{value: fee}("");
amount -= fee;
roundData.bearBetsAmount += amount;
roundData.totalEthBets += amount;
userData.bearEntries += amount;
userData.totalEthBetted += amount;
_userBetRounds[msg.sender].add(roundID + 1);
emit BetBear(msg.sender, roundID + 1, amount);
}
function bullShare(
address user,
uint256 _roundID
) public view returns (uint256 share) {
Round storage roundData = rounds[_roundID];
UserEntries storage userData = userEntries[user][_roundID];
uint256 bullAmnt = roundData.bullBetsAmount;
uint256 betAmnt = userData.bullEntries;
if (betAmnt > 0) {
share = (betAmnt * 10_000) / bullAmnt;
} else {
share = 0;
}
}
function bearShare(
address user,
uint256 _roundID
) public view returns (uint256 share) {
Round storage roundData = rounds[_roundID];
UserEntries storage userData = userEntries[user][_roundID];
uint256 bearAmnt = roundData.bearBetsAmount;
uint256 betAmnt = userData.bearEntries;
if (betAmnt > 0) {
share = (betAmnt * 10_000) / bearAmnt;
} else {
share = 0;
}
}
function bullMutiplier(uint256 _roundID) public view returns (uint256) {
Round storage roundData = rounds[_roundID];
uint256 bulls = roundData.bullBetsAmount;
uint256 bears = roundData.bearBetsAmount;
uint256 multipiler;
if (bulls > 0 && bears > 0) {
multipiler = 10_000 + ((bears * 10_000) / bulls);
} else if (bears > 0 && bulls == 0) {
multipiler = 10_000 + ((bears * 10_000) / minimumBet);
} else {
multipiler = 10_000;
}
return multipiler;
}
function bearMutiplier(uint256 _roundID) public view returns (uint256) {
Round storage roundData = rounds[_roundID];
uint256 bulls = roundData.bullBetsAmount;
uint256 bears = roundData.bearBetsAmount;
uint256 multipiler;
if (bears > 0 && bulls > 0) {
multipiler = 10_000 + ((bulls * 10_000) / bears);
} else if (bulls > 0 && bears == 0) {
multipiler = 10_000 + ((bulls * 10_000) / minimumBet);
} else {
multipiler = 10_000;
}
return multipiler;
}
function rewardBullsClaimableAmntsView(
address user,
uint256 _roundID
) public view returns (uint256 amountClaimable) {
Round storage roundData = rounds[_roundID];
UserEntries storage userData = userEntries[user][_roundID];
uint256 userShare = bullShare(user, _roundID);
uint256 totalEthPot = roundData.totalEthBets;
bool isClaimable = totalEthPot > 0 &&
userShare > 0 &&
roundData.roundClose &&
roundResult(_roundID);
amountClaimable = 0;
if (isClaimable) {
amountClaimable = (totalEthPot * userShare) / 10_000;
} else if (
!roundResult(_roundID) &&
roundData.bearBetsAmount == 0 &&
userShare > 0
) {
amountClaimable = userData.bullEntries;
}
}
function rewardBearsClaimableAmntsView(
address user,
uint256 _roundID
) public view returns (uint256 amountClaimable) {
Round storage roundData = rounds[_roundID];
UserEntries storage userData = userEntries[user][_roundID];
uint256 userShare = bearShare(user, _roundID);
uint256 totalEthPot = roundData.totalEthBets;
bool isClaimable = totalEthPot > 0 &&
userShare > 0 &&
roundData.roundClose &&
!roundResult(_roundID);
amountClaimable = 0;
if (isClaimable) {
amountClaimable = (totalEthPot * userShare) / 10_000;
} else if (
roundResult(_roundID) &&
roundData.bullBetsAmount == 0 &&
roundData.roundClose &&
userShare > 0
) {
amountClaimable = userData.bearEntries;
}
}
function rewardBullsClaimableAmnts(
address user,
uint256 _roundID
) public view returns (uint256 amountClaimable) {
Round storage roundData = rounds[_roundID];
UserEntries storage userData = userEntries[user][_roundID];
uint256 userShare = bullShare(user, _roundID);
uint256 totalEthPot = roundData.totalEthBets;
bool isClaimable = totalEthPot > 0 &&
userShare > 0 &&
roundData.roundClose &&
roundResult(_roundID) &&
!userData.bullClaimed;
if (isClaimable) {
amountClaimable = (totalEthPot * userShare) / 10_000;
} else if (
!roundResult(_roundID) &&
roundData.bearBetsAmount == 0 &&
userShare > 0 &&
roundData.roundClose &&
!userData.bullClaimed
) {
amountClaimable = userData.bullEntries;
}
}
function rewardBearsClaimableAmnts(
address user,
uint256 _roundID
) public view returns (uint256 amountClaimable) {
Round storage roundData = rounds[_roundID];
UserEntries storage userData = userEntries[user][_roundID];
uint256 userShare = bearShare(user, _roundID);
uint256 totalEthPot = roundData.totalEthBets;
bool isClaimable = totalEthPot > 0 &&
userShare > 0 &&
roundData.roundClose &&
!roundResult(_roundID) &&
!userData.bearClaimed;
if (isClaimable) {
amountClaimable = (totalEthPot * userShare) / 10_000;
} else if (
roundResult(_roundID) &&
roundData.bullBetsAmount == 0 &&
userShare > 0 &&
!userData.bearClaimed
) {
amountClaimable = userData.bearEntries;
}
}
function claimBull(
address user,
uint256 _roundID
) internal returns (uint256 amntClaimed) {
UserEntries storage userData = userEntries[user][_roundID];
uint256 userShare = bullShare(user, _roundID);
require(userShare > 0, "No claims");
require(!userData.bullClaimed, "already claimed");
require(!isEven(_roundID));
uint256 totalAmntWon = rewardBullsClaimableAmnts(user, _roundID);
bool success;
(success, ) = address(user).call{value: totalAmntWon}("");
userData.totalEthWon += totalAmntWon;
userData.bullClaimed = true;
IPredictionFactory(predictionFactory).addEthPayout(totalAmntWon);
amntClaimed = totalAmntWon;
emit BullClaimed(user, _roundID, totalAmntWon);
}
function claimBear(
address user,
uint256 _roundID
) internal returns (uint256 amntClaimed) {
UserEntries storage userData = userEntries[user][_roundID];
uint256 userShare = bearShare(user, _roundID);
require(userShare > 0, "No claims");
require(!userData.bearClaimed, "already claimed");
require(!isEven(_roundID));
uint256 totalAmntWon = rewardBearsClaimableAmnts(user, _roundID);
bool success;
(success, ) = address(user).call{value: totalAmntWon}("");
userData.totalEthWon += totalAmntWon;
userData.bearClaimed = true;
IPredictionFactory(predictionFactory).addEthPayout(totalAmntWon);
amntClaimed = totalAmntWon;
emit BearClaimed(user, _roundID, totalAmntWon);
}
function claimWinnings(address user, uint256 _roundID) public nonReentrant {
Round storage roundData = rounds[_roundID];
UserEntries storage userData = userEntries[user][_roundID];
uint256 userBullShare = bullShare(user, _roundID);
uint256 userBearShare = bearShare(user, _roundID);
require(roundData.roundClose, "Round is not closed");
require(userBullShare > 0 || userBearShare > 0, "Nothing to claim");
if (roundResult(_roundID) && !isEven(_roundID) && userBullShare > 0) {
totalEthPayoutsMade += claimBull(user, _roundID);
} else if (
!roundResult(_roundID) && !isEven(_roundID) && userBearShare > 0
) {
totalEthPayoutsMade += claimBear(user, _roundID);
} else if (isEven(_roundID)) {
if (userBullShare > 0) {
bool success;
(success, ) = address(user).call{value: userData.bullEntries}(
""
);
totalEthPayoutsMade += userData.bullEntries;
userData.totalEthWon += userData.bullEntries;
userData.bullClaimed = true;
emit BullClaimed(user, _roundID, userData.bullEntries);
} else if (userBearShare > 0) {
bool success;
(success, ) = address(user).call{value: userData.bearEntries}(
""
);
totalEthPayoutsMade += userData.bearEntries;
userData.totalEthWon += userData.bearEntries;
userData.bearClaimed = true;
emit BearClaimed(user, _roundID, userData.bullEntries);
}
}
if (
userBullShare > 0 &&
roundData.bearBetsAmount == 0 &&
!roundResult(_roundID) &&
!userData.bullClaimed
) {
totalEthPayoutsMade += claimBull(user, _roundID);
}
if (
userBearShare > 0 &&
roundData.bullBetsAmount == 0 &&
roundResult(_roundID) &&
!userData.bearClaimed
) {
totalEthPayoutsMade += claimBear(user, _roundID);
}
}
function hasEthLiquidity(address tokenAddress) public view returns (bool) {
address[] memory path = new address[](2);
path[0] = tokenAddress;
path[1] = IUniswapV2Router01(router).WETH();
try IUniswapV2Router01(router).getAmountsOut(0.01 ether, path) returns (
uint256[] memory amounts
) {
return amounts[1] > 0;
} catch {
return false;
}
}
}
文件 13 的 16:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
文件 14 的 16:RefProgramCodeGenerator.sol
pragma solidity >=0.8.2 <0.9.0;
contract RefProgramCodeGenerator {
function generatedNonce(
address user,
uint256 roundID
) public pure returns (uint256) {
uint256 id = uint256(
keccak256(abi.encodePacked(user, roundID))
) % 9999;
uint256 randomNumber = uint256(keccak256(abi.encodePacked(id, user)));
return randomNumber;
}
}
文件 15 的 16:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 16 的 16:Types.sol
pragma solidity ^0.8.12;
enum Module {
RESOLVER,
TIME,
PROXY,
SINGLE_EXEC
}
struct ModuleData {
Module[] modules;
bytes[] args;
}
interface IAutomate {
function createTask(
address execAddress,
bytes calldata execDataOrSelector,
ModuleData calldata moduleData,
address feeToken
) external returns (bytes32 taskId);
function cancelTask(bytes32 taskId) external;
function getFeeDetails() external view returns (uint256, address);
function gelato() external view returns (address payable);
function taskTreasury() external view returns (ITaskTreasuryUpgradable);
}
interface ITaskTreasuryUpgradable {
function depositFunds(
address receiver,
address token,
uint256 amount
) external payable;
function withdrawFunds(
address payable receiver,
address token,
uint256 amount
) external;
}
interface IOpsProxyFactory {
function getProxyOf(address account) external view returns (address, bool);
}
interface IGelato {
function feeCollector() external view returns (address);
}
{
"compilationTarget": {
"contracts/PredictionMarket.sol": "PredictionMarket"
},
"evmVersion": "shanghai",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_automate","type":"address"},{"internalType":"address","name":"_fundsOwner","type":"address"}],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountClaimed","type":"uint256"}],"name":"BearClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"round","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BetBear","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"round","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BetBull","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountClaimed","type":"uint256"}],"name":"BullClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"taskId","type":"bytes32"}],"name":"CounterTaskCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"automate","outputs":[{"internalType":"contract IAutomate","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundID","type":"uint256"}],"name":"bearMutiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"_roundID","type":"uint256"}],"name":"bearShare","outputs":[{"internalType":"uint256","name":"share","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bettingOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bufferTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundID","type":"uint256"}],"name":"bullMutiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"_roundID","type":"uint256"}],"name":"bullShare","outputs":[{"internalType":"uint256","name":"share","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checker","outputs":[{"internalType":"bool","name":"canExec","type":"bool"},{"internalType":"bytes","name":"execPayload","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"_roundID","type":"uint256"}],"name":"claimWinnings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"createTask","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dedicatedMsgSender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_token","type":"address"}],"name":"depositFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"refCode","type":"uint256"}],"name":"enterBear","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"refCode","type":"uint256"}],"name":"enterBull","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"fundsOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"code","type":"uint256"}],"name":"getCodesUsedAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"code","type":"uint256"}],"name":"getCodesUsedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"roundId","type":"uint256"}],"name":"getRoundInfo","outputs":[{"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"internalType":"uint256","name":"expireTimestamp","type":"uint256"},{"internalType":"uint256","name":"openPrice","type":"uint256"},{"internalType":"uint256","name":"closePrice","type":"uint256"},{"internalType":"uint256","name":"bearBetsAmount","type":"uint256"},{"internalType":"uint256","name":"bullBetsAmount","type":"uint256"},{"internalType":"uint256","name":"totalEthBets","type":"uint256"},{"internalType":"bool","name":"roundClose","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenPriceUSD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserActivatedCodes","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserActivatedCodesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"roundId","type":"uint256"}],"name":"getUserEntries","outputs":[{"internalType":"uint256","name":"bullEntries","type":"uint256"},{"internalType":"uint256","name":"bearEntries","type":"uint256"},{"internalType":"uint256","name":"totalEthBetted","type":"uint256"},{"internalType":"uint256","name":"totalEthWon","type":"uint256"},{"internalType":"bool","name":"bullClaimed","type":"bool"},{"internalType":"bool","name":"bearClaimed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserGeneratedCodes","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserGeneratedCodesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserRounds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"hasEthLiquidity","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"code","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"isCodeUsable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundID","type":"uint256"}],"name":"isEven","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRefProgramOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isStopped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumBet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newRoundStartable","outputs":[{"internalType":"bool","name":"canExec","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"predictionFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"_roundID","type":"uint256"}],"name":"rewardBearsClaimableAmnts","outputs":[{"internalType":"uint256","name":"amountClaimable","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"_roundID","type":"uint256"}],"name":"rewardBearsClaimableAmntsView","outputs":[{"internalType":"uint256","name":"amountClaimable","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"_roundID","type":"uint256"}],"name":"rewardBullsClaimableAmnts","outputs":[{"internalType":"uint256","name":"amountClaimable","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"_roundID","type":"uint256"}],"name":"rewardBullsClaimableAmntsView","outputs":[{"internalType":"uint256","name":"amountClaimable","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roundID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roundPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundID","type":"uint256"}],"name":"roundResult","outputs":[{"internalType":"bool","name":"isBull","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"setPoolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newRoundPeriod","type":"uint256"}],"name":"setRoundPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startNewRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"taskId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taskTreasury","outputs":[{"internalType":"contract ITaskTreasuryUpgradable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCodesUsed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalEthPayoutsMade","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateRefProgrammStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]