Skip to content

Instantly share code, notes, and snippets.

@yohanesyuen
Last active January 23, 2024 12:14
Show Gist options
  • Save yohanesyuen/d7fb34326be848b78a11d968a5a7c66c to your computer and use it in GitHub Desktop.
Save yohanesyuen/d7fb34326be848b78a11d968a5a7c66c to your computer and use it in GitHub Desktop.
// Donation address: 17Ez2fRkxxwwTh6W8njm4rhWdrphxRiDa1
// Sign up link: https://freebitco.in/?r=3329532
function Random(seed) {
this.m = Math.pow(2, 32);
this.maxIdx = 128;
this.buf = new Uint32Array(this.maxIdx);
this.idx = 0;
window.crypto.getRandomValues(this.buf);
}
Random.prototype.next = function() {
if (this.idx >= this.maxIdx) {
window.crypto.getRandomValues(this.buf);
this.idx = 0;
}
return this.buf[this.idx++];
};
Random.prototype.nextFloat = function() {
return this.next() / this.m;
};
var rand = new Random();
function messify() {
var maxMessCount = rand.nextFloat() * rand.maxIdx;
var messCount = Math.floor(rand.nextFloat() * maxMessCount);
var seed = '';
for (var i = 0; i < messCount; i++) {
// rand.next();
seed = reseed(true, seed);
}
reseed(false, seed);
}
function formatTime(seconds) {
var sign = "";
if (seconds < 0) {
sign = "-";
}
var quotient, _seconds, _minutes, _hours, _days, _str;
quotient = Math.floor(Math.abs(seconds));
_seconds = quotient % 60;
quotient -= _seconds;
quotient /= 60;
_minutes = quotient % 60;
quotient -= _minutes;
quotient /= 60;
_hours = quotient % 24;
quotient -= _hours;
quotient /= 24;
_days = quotient;
_str = sign + (_days > 0 ? _days + "d " : "");
_str += _hours < 10 ? "0" + _hours : _hours;
_str += ":";
_str += _minutes < 10 ? "0" + _minutes : _minutes;
_str += ":";
_str += _seconds < 10 ? "0" + _seconds : _seconds;
return _str;
}
var startValue = "0.00000001",
seed = "",
extraSeed = 0,
targetLs = 17,
ls = targetLs,
minimumBalance = Math.pow(2, ls) * 1e-8,
multiplier = 2.1,
stopPercentage = 0.01,
minWaitDefault = 3,
maxWaitDefault = minWaitDefault * 2,
minWait = minWaitDefault,
maxWait = maxWaitDefault,
stopped = false,
stopBefore = 3,
originalBalance = 0,
beforeStreakBalance = 0,
averageStartTime = Date.now(),
gameStartTime = Date.now(),
wageredAmount = 0,
resetThreshold = 3e-8,
targetHitCount = 0,
targetValue = 0.00242780,
autoset_payout = false,
run_period = 10 * 60 * 1000,
pause_period = 5 * 60 * 1000,
btcsgd = 3e4;
var bets = 0,
lossStreak = 0,
maxLossStreak = [],
streakProfit = 0,
wins = 0,
loss = 0;
var $loButton = $("#double_your_btc_bet_lo_button"),
$hiButton = $("#double_your_btc_bet_hi_button"),
$stake = $("#double_your_btc_stake"),
$payout = $("#double_your_btc_payout_multiplier"),
$lose = $("#double_your_btc_bet_lose"),
$win = $("#double_your_btc_bet_win"),
$err = $("#double_your_btc_error"),
$bal = $("#balance"),
$baBal = $("#bonus_account_balance"),
$funBuyPrice = $("#fun_buy_price"),
$buyFunCount = $("#buy_fun_count"),
$buyFunConfirm = $("#buy_fun_confirm"),
$btn = $loButton,
thresholds = [0, 1],
payoutTable = [4, 3];
var timeouts = {
'win': -1,
'lose': -1,
'start': -1,
'stop': -1
};
var intervals = {
'statPrinter': -1,
}
var lastBetWin = false,
side = "lo";
var BettingProfile, BettingProfiles;
BettingProfile = function(startBet, options) {
var options = options || {};
this.startValue = typeof startBet === 'number' ? startBet.toFixed(8) : startBet;
this.multiplier = options.multiplier || 2.0;
this.minimumBalance = 0;
this.safetyAmount = 0;
this.targetValue = 0;
this.maxLoss = 0;
this.maxBetCount = 0;
this.balanceAfterLoss = 0;
this.balance = options.balance;
var currentBet = parseFloat(this.startValue);
while (this.maxLoss + currentBet < this.balance) {
this.maxBetCount += 1;
this.maxLoss += currentBet;
currentBet *= this.multiplier;
currentBet = parseFloat(currentBet.toFixed(8));
}
this.minimumBalance = this.maxLoss.toFixed(8);
this.balanceAfterLoss = (this.balance - this.maxLoss).toFixed(8);
this.targetValue = parseFloat((currentBet + this.maxLoss).toFixed(8));
}
BettingProfiles = (function() {
var getForBalance, getProfiles;
getForBalance = function(balance) {
var profiles = getProfiles(balance);
return profiles[profiles.length - 1];
}
getStartValue = function(balance) {
var mul = Math.floor(balance / (Math.pow(2, targetLs) * 1e-8));
return mul > 0 ? mul * 1e-8 : 1e-8;
}
getProfiles = function(balance) {
console.log('getProfiles called');
var profiles = [];
var multipliers = [];
var increment = 0.001;
var startValue = getStartValue(balance);
for (var i = 0; i <= 10000; i++) {
multipliers.push(2 + i * increment);
}
multipliers.forEach(multiplier => {
profiles.push(
new BettingProfile(startValue, {
multiplier: multiplier,
balance: balance
})
);
});
var maxBetCountValue = Math.max.apply(Math, profiles.map(p => p.maxBetCount));
profiles = profiles.filter(p => p.maxBetCount >= maxBetCountValue - 1)
profiles = profiles.sort((a, b) => (a.balanceAfterLoss > b.balanceAfterLoss) ? 1 : -1);
return profiles;
}
return {
getForBalance: getForBalance,
getProfiles: getProfiles
};
})();
function clearBindings() {
$lose.unbind();
$win.unbind();
$err.unbind();
}
function getBalance() {
var mainBal = parseFloat($bal.text());
var baBal = parseFloat($baBal.text());
return mainBal + baBal;
}
function getLs() {
desiredLS = 17;
ls = Math.floor(Math.log2(getBalance() / 1e-8))
ls = ls > desiredLS - 1 ? desiredLS : ls;
return ls;
}
function randomIntFromInterval(min, max) {
return Math.floor(rand.nextFloat() * (max - min + 1) + min);
}
function bufferToHex(buffer) {
return Array
.from(buffer)
.map(b => b.toString(16).padStart(2, "0"))
.join("");
}
function reseed(virtual = false, seed = '') {
var buf = new Uint32Array(8),
hexbuf = ''
suffix = '';
window.crypto.getRandomValues(buf);
hexbuf = bufferToHex(buf);
suffix = Date.now().toString(16) + rand.next().toString(16)
seed += hexbuf.substr(0, hexbuf.length - suffix.length) + Date.now() + rand.next() + extraSeed;
seed = CryptoJS.SHA256(seed).toString()
if (!virtual) {
$("#next_client_seed").val(seed);
} else {
return seed;
}
}
function resetProfileOnStakeEqBal(stake) {
if (stake > getBalance() || stake == getBalance()) {
clearTimeout(timeouts.lose);
resetProfile();
stake = parseFloat(startValue);
}
}
function multiply() {
var current = $stake.val();
var x = current * multiplier;
resetProfileOnStakeEqBal(x);
$stake.val(x.toFixed(8));
CalculateWinAmount();
}
function getRandomWait() {
var wait = randomIntFromInterval(minWait, maxWait);
console.log("Waiting for " + wait + " ms");
return wait;
}
function reset() {
$stake.val(startValue);
CalculateWinAmount();
lossStreak = 0;
beforeStreakBalance = getBalance();
}
function resetStartValues() {
originalBalance = getBalance();
wageredAmount = 0;
gameStartTime = Date.now();
}
function resetProfile() {
var profile = BettingProfiles.getForBalance(getBalance());
multiplier = profile.multiplier;
startValue = profile.startValue;
targetValue = profile.targetValue;
}
function initGame() {
originalBalance = getBalance();
// ls = getBalance() > Math.pow(2, 15) * 1e-8 ? getLs() - 1 : getLs();
ls = getLs();
minimumBalance = Math.pow(2, 11) * 1e-8;
if (originalBalance < minimumBalance) {
return;
}
resetProfile();
reseed();
reset();
}
function startGame() {
console.log("Game started!");
initGame();
$btn.trigger("click");
timeouts.stop = setTimeout(stopGame, run_period);
}
function stopGame() {
console.log("Game will stop soon! Let me finish.");
stopped = true;
timeouts.start = setTimeout(startGame, pause_period);
}
function deexponentize(number) {
return number * 1000000;
}
function iHaveEnoughMoney() {
var balance = deexponentize(getBalance());
var current = deexponentize($stake.val());
return ((balance * multiplier) / 100) * (current * multiplier) > stopPercentage / 100;
}
function stopBeforeRedirect() {
var minutes = parseInt($("title").text());
if (minutes < stopBefore) {
console.log("Approaching redirect! Stop the game so we don't get redirected while losing.");
stopGame();
}
}
function switchSide() {
side = side === "lo" ? "hi" : "lo";
}
function nextClick() {
var x = parseFloat($stake.val());
var a = parseFloat(startValue);
// var proposedPayoutValue = 2 + Math.floor(ls / 6 - lossStreak)
// $payout.val((proposedPayoutValue) > 2 ? proposedPayoutValue : 2 );
printStats();
if (lastBetWin) {
switchSide();
$btn = $("#double_your_btc_bet_" + side + "_button");
} else {
reseed();
}
$btn.trigger("click");
}
function getProfit() {
return getBalance() - originalBalance;
}
function incrementStartValue() {
startValue = parseFloat(startValue) + 1e-8;
startValue = startValue.toFixed(8);
resetStartValues();
}
function decrementStartValue() {
startValue = parseFloat(startValue) - 1e-8;
startValue = startValue.toFixed(8);
resetStartValues();
}
function stopOnBonusCrossBalance() {
var baBal = parseFloat($baBal.text());
if (baBal >= balance) {
stopped == true;
clearBindings();
}
}
function resetOnTargetHit() {
if (getBalance() >= targetValue) {
ls = Math.floor(Math.log2(getBalance() / 1e-8))
ls = ls > targetLs - 1 ? targetLs : ls;
resetProfile();
if (ls >= targetLs) {
return;
}
targetHitCount += 1;
if (getBalance() < Math.pow(2, targetLs) * 1e-8 && targetHitCount > (targetLs - ls)) {
stopped = true;
clearBindings();
clearInterval(intervals.statPrinter);
document.location.reload();
return;
}
}
}
function printStats() {
console.clear();
var css = "background-color: black; color: #0f0; font-size: 10pt";
var elapsedTime = Date.now() - gameStartTime;
var elapsedSeconds = Math.floor(elapsedTime / 1000);
var sgdBalance = getBalance() * btcsgd;
var sgdProfit = (getBalance() - originalBalance) * btcsgd;
var perSecondSgdProfit = sgdProfit / elapsedSeconds;
perSecondSgdProfit -= (perSecondSgdProfit / elapsedSeconds);
var perMinuteSgdProfit = perSecondSgdProfit * 60;
var perHourSgdProfit = perMinuteSgdProfit * 60;
targetValueSgd = targetValue * btcsgd;
var str = "Balance:\t\t\t\tS$ " + sgdBalance.toFixed(4) + "\t| ";
str += "Profit since start:\tS$ " + sgdProfit.toFixed(4) + "\t| ";
str += "Rate of earnings: S$ " + perHourSgdProfit.toFixed(4) + "/hour";
str += "\n";
str += "Time before S$" + targetValueSgd.toFixed(2) + ":\t";
str += formatTime((targetValueSgd - sgdBalance) / perSecondSgdProfit) + "\t| ";
str += "Total Wagered:\tBTC " + wageredAmount.toFixed(8) + "\t| ";
str += "Time since start:\t" + formatTime(elapsedSeconds);
str += "\n";
str += "Multiplier: " + multiplier.toFixed(4) + "\t\t\t\t\t| ";
// str += "Extra Seed: " + extraSeed.toString() + "\t\t\t\t| ";
str += "Distance to next: BTC " + ((
Math.ceil(
getBalance() / Math.pow(2,targetLs) / 1e-8) * Math.pow(2, targetLs) * 1e-8
) - getBalance()).toFixed(8) + "\t| ";
str += "Fun Budget: " + parseFloat(localStorage.getItem("pendingFunBudget")).toFixed(8);
str = "%c" + str;
console.log(str, css);
}
clearBindings();
function buyFunIfBudgetAllows() {
var currentPrice = parseFloat($funBuyPrice.text());
if (wins % 4 == 0) {
var currentBudget = localStorage.getItem("pendingFunBudget");
var currentPrice;
if (currentBudget === null) {
localStorage.setItem("pendingFunBudget", 1e-8.toFixed(8));
} else {
currentBudget = parseFloat(currentBudget);
var buyCount = Math.floor(currentBudget / currentPrice);
var spending = buyCount * currentPrice;
if (buyCount > 0) {
$buyFunCount.val(buyCount);
$buyFunConfirm.click();
localStorage.setItem(
"pendingFunBudget",
(parseFloat(localStorage.getItem("pendingFunBudget")) + parseFloat(startValue) - spending).toFixed(8));
} else {
localStorage.setItem(
"pendingFunBudget",
(parseFloat(localStorage.getItem("pendingFunBudget")) + parseFloat(startValue)).toFixed(8));
}
}
}
}
$lose.bind("DOMSubtreeModified", function(event) {
if ($(event.currentTarget).is(':contains("lose")')) {
lossStreak++;
loss++;
bets++;
wageredAmount += $stake.val() * 1;
lastBetWin = false;
if (lossStreak > Math.floor(Math.sqrt(Math.log2(balance / 1e-8)))) {
$payout.val(2);
}
minWait = Math.ceil(minWait * (1 + rand.nextFloat()));
maxWait = Math.ceil(minWait * (1 + rand.nextFloat()));
messify();
streakProfit -= $stake.val();
// console.log('Lose - StreakProfit: ' + streakProfit.toFixed(8));
multiply();
if (getBalance() > minimumBalance) {
timeouts.lose = setTimeout(nextClick, randomIntFromInterval(minWait, maxWait));
}
}
});
$win.bind("DOMSubtreeModified", function(event) {
if ($(event.currentTarget).is(":contains('win')")) {
if (maxLossStreak[lossStreak]) {
maxLossStreak[lossStreak] = maxLossStreak[lossStreak] + 1;
} else {
maxLossStreak[lossStreak] = 1;
}
wins++;
bets++;
lastBetWin = true;
wageredAmount += $stake.val() * 1;
streakProfit += parseFloat($win.text().split(' ')[6]);
// console.log('Win - StreakProfit: ' + streakProfit.toFixed(8));
minWait = minWaitDefault;
maxWait = maxWaitDefault;
resetOnTargetHit();
stopOnBonusCrossBalance();
stopBeforeRedirect();
buyFunIfBudgetAllows();
if (stopped) {
stopped = true;
clearBindings();
clearInterval(intervals.statPrinter);
return;
}
if (iHaveEnoughMoney()) {
reset();
}
timeouts.win = setTimeout(nextClick, randomIntFromInterval(minWait, maxWait));
}
});
$err.bind("DOMSubtreeModified", function(event) {
if ($(event.currentTarget).is(':contains("timed out")')) {
console.log("Request timed out! :( But we're betting again!");
nextClick();
}
});
setInterval(function() {
if ($('#bonus_eligible_msg').is(':visible')) {
$('#claim_bonus_link').click();
setTimeout(function() {
$('#accept_bonus_terms').prop('checked', true);
$('#claim_bonus_button').click();
}, 2000);
}
}, 10000);
window.onmousemove = e => {
extraSeed = e.clientX * e.clientY;
reseed(true);
};
function updatePrice() {
fetch('https://api.gemini.com/v1/pubticker/btcsgd')
.then(res => res.json())
.then(data => {
btcsgd = data.last;
console.log(data.last);
});
setTimeout(updatePrice, 5000);
}
run_period = 500 * 6e4;
pause_period = 5 * 6e4;
SwitchPageTabs("double_your_btc");
// btcsgd = 3.7e4;
// targetLs -= 1;
startGame();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment