Full source code:https://github.com/laronlineworld/prediction/blob/main/Prediction.sol
This Prediction (of price feed from oracle) smart contract can bet a BNB, the problem is I want to change the BNB into BTC as token to bet:
How user choose what to bet: This function use _safetransferBNB for external payable. How to change the bnb into BTC as token to bet?
/**
* @notice Bet bear position
* @param epoch: epoch
*/
function betBear(uint256 epoch) external payable whenNotPaused nonReentrant notContract {
require(epoch == currentEpoch, "Bet is too early/late");
require(_bettable(epoch), "Round not bettable");
require(msg.value >= minBetAmount, "Bet amount must be greater than minBetAmount");
require(ledger[epoch][msg.sender].amount == 0, "Can only bet once per round");
// Update round data
uint256 amount = msg.value;
Round storage round = rounds[epoch];
round.totalAmount = round.totalAmount + amount;
round.bearAmount = round.bearAmount + amount;
// Update user data
BetInfo storage betInfo = ledger[epoch][msg.sender];
betInfo.position = Position.Bear;
betInfo.amount = amount;
userRounds[msg.sender].push(epoch);
emit BetBear(msg.sender, epoch, amount);
}
/**
* @notice Bet bull position
* @param epoch: epoch
*/
function betBull(uint256 epoch) external payable whenNotPaused nonReentrant notContract {
require(epoch == currentEpoch, "Bet is too early/late");
require(_bettable(epoch), "Round not bettable");
require(msg.value >= minBetAmount, "Bet amount must be greater than minBetAmount");
require(ledger[epoch][msg.sender].amount == 0, "Can only bet once per round");
// Update round data
uint256 amount = msg.value;
Round storage round = rounds[epoch];
round.totalAmount = round.totalAmount + amount;
round.bullAmount = round.bullAmount + amount;
// Update user data
BetInfo storage betInfo = ledger[epoch][msg.sender];
betInfo.position = Position.Bull;
betInfo.amount = amount;
userRounds[msg.sender].push(epoch);
emit BetBull(msg.sender, epoch, amount);
}
Calculation of rewards and how claim function works
/**
* @notice Claim reward for an array of epochs
* @param epochs: array of epochs
*/
function claim(uint256[] calldata epochs) external nonReentrant notContract {
uint256 reward; // Initializes reward
for (uint256 i = 0; i < epochs.length; i++) {
require(rounds[epochs[i]].startTimestamp != 0, "Round has not started");
require(block.timestamp > rounds[epochs[i]].closeTimestamp, "Round has not ended");
uint256 addedReward = 0;
// Round valid, claim rewards
if (rounds[epochs[i]].oracleCalled) {
require(claimable(epochs[i], msg.sender), "Not eligible for claim");
Round memory round = rounds[epochs[i]];
addedReward = (ledger[epochs[i]][msg.sender].amount * round.rewardAmount) / round.rewardBaseCalAmount;
}
// Round invalid, refund bet amount
else {
require(refundable(epochs[i], msg.sender), "Not eligible for refund");
addedReward = ledger[epochs[i]][msg.sender].amount;
}
ledger[epochs[i]][msg.sender].claimed = true;
reward += addedReward;
emit Claim(msg.sender, epochs[i], addedReward);
}
if (reward > 0) {
_safeTransferBNB(address(msg.sender), reward);
}
}