Buy and burn on a schedule
Tested on BSC testnet before every release
This is an example. Every value in it (names, amounts, addresses) is there to show you how; change any of them to suit you. It’s recipe-burn-schedule.mjs, exactly as our tests run it on testnet. Point it at testnet with MM_API, or leave it for mainnet.
// Buy-and-burn on a schedule: every so often, buy a fixed amount of a token and// send what you bought to the dead address, for ever. Each round is two// transactions you can show people: the buy, and the burn.// PRIVATE_KEY=0x… TOKEN=0x… node recipe-burn-schedule.mjs//// Every setting has a cap you choose on purpose:// SPEND=0.01 BNB per round// EVERY_MINUTES=60 minutes between rounds// MAX_TOTAL=0.1 BNB across the whole run; it stops after this// RUNS= stop after this many rounds (default: until MAX_TOTAL)import { MarketMayhem } from '@marketmayhem/sdk';import { Contract, JsonRpcProvider, Wallet, formatUnits } from 'ethers';
const DEAD = '0x000000000000000000000000000000000000dEaD';const token = process.env.TOKEN;const spend = Number(process.env.SPEND ?? '0.01');const everyMs = Number(process.env.EVERY_MINUTES ?? '60') * 60_000;const maxTotal = Number(process.env.MAX_TOTAL ?? '0.1');const runs = process.env.RUNS ? Number(process.env.RUNS) : Infinity;if (!token || !(spend > 0) || !(maxTotal >= spend)) throw new Error('Set TOKEN, and SPEND no bigger than MAX_TOTAL.');
const mm = MarketMayhem.fromPrivateKey(process.env.PRIVATE_KEY, { api: process.env.MM_API });const { chainId } = await mm.settings();const rpc = chainId === 56 ? 'https://bsc-dataseed.bnbchain.org' : 'https://bsc-testnet-rpc.publicnode.com';const wallet = new Wallet(process.env.PRIVATE_KEY, new JsonRpcProvider(rpc, chainId));const erc20 = new Contract(token, ['function balanceOf(address) view returns (uint256)', 'function transfer(address, uint256) returns (bool)', 'function decimals() view returns (uint8)'], wallet);const decimals = await erc20.decimals();
let spent = 0;let round = 0;const burned = [];while (round < runs && spent + spend <= maxTotal + 1e-12) { round += 1; // Burn exactly what this round bought: the balance before and after, not the whole wallet. const before = await erc20.balanceOf(wallet.address); const buy = await mm.buy(token, { spend: String(spend) }); const bought = (await erc20.balanceOf(wallet.address)) - before; const burn = await (await erc20.transfer(DEAD, bought)).wait(); spent += spend; burned.push({ buy: buy.hash, burn: burn.hash }); console.log(`round ${round}: bought ${formatUnits(bought, decimals)} for ${spend} BNB (${buy.hash}), burned them (${burn.hash})`); if (round < runs && spent + spend <= maxTotal + 1e-12) await new Promise((r) => setTimeout(r, everyMs));}console.log(`done: ${round} round(s), ${spent} BNB spent`);console.log('RESULT', JSON.stringify({ rounds: round, spent, burned }));