THIS CODE WAS RAPIDLY PROTOTYPED ("VIBE CODED") FOR A SPECIFIC USE CASE.
- This is NOT production-grade software - Developed iteratively under extreme time pressure
- Code quality is experimental - Limited testing, rapid iterations, many edge cases unhandled
- Use at your own risk - You can lose funds. Thoroughly audit before deploying real money.
- No warranty or guarantees - The authors assume ZERO responsibility for losses
- Educational/research purposes only - Not recommended for production use without extensive modifications
IF YOU USE THIS CODE:
- Understand every line - Don't run code you don't comprehend
- Test exhaustively - Use testnets and small amounts first
- Audit thoroughly - Have security experts review the code
- Accept full responsibility - You own all risks and consequences
- Configure your own RPCs - Do NOT use others' private/premium RPC endpoints
src/main-rbf.ts) is now the PRIMARY/PRODUCTION bot. The Original Bot (src/index.ts) is LEGACY/DEPRECATED.
Command: npm run start:rbf (production) or npm run start:rbf:dry (dry-run test)
A hardened, ultra-low-latency Node.js/TypeScript bot optimized for first-in-window execution using Shotgun RBF Strategy - block-event driven architecture with escalating gas (200x → 1,223x). It watches the MiTeddy contract and fires with maximum gas (50.0x = 12,500 Gwei) the instant a slot opens. Features include:
- Battering Ram Mode: Starts at maximum gas (50.0x) immediately - no ramp-up
- Event-driven triggers via WebSocket block subscription (~0-50ms detection)
- Aggressive pre-warming with maximum gas (starts 5 minutes early, 50.0x gas)
- Pre-signed nuclear TX ready instantly (50.0x gas)
- Nonce-synced pre-sign cache re-signs nuclear + fee-capped payloads the moment the chain nonce advances, so stale blobs are never rebroadcast
- Dual-branch strategy (primary RBF + shadow new-nonce at 75.0x)
- Tiered multi-RPC broadcast - top-N fastest RPCs fire first, then the rest if no hash lands (
RPC_PRIMARY_FANOUTcontrols fan-out) - Predictive pre-warm simulation - dual-RPC
eth_callscouts prevent wasted gas while the contract is still locked (auto-bypassed in final 5 s) - Aggressive spam reuse - time-based spam now rides the tiered broadcaster + private RPC client, keeping 40 tx/sec without hammering every endpoint
- Gas limit persistence - every successful mint seeds the fallback gas limit (with a 20 % buffer) to keep nuclear burns tight
- Time-based spam mode (42s before expected, 42s after, 40 tx/sec)
- State persistence for crash recovery
- Circuit breaker for RPC health monitoring
For New Users:
- Getting Started - Complete first-time setup guide
- Quick Start - Get started in 5 minutes
- Runbook - Quick start guide, monitoring, and troubleshooting
- Configuration Guide - Complete configuration reference
Recent Updates & Fixes:
- Changelog - Complete list of changes and improvements in November 2025
- Post-Mortem Analysis - Detailed analysis of 11:11 window failure and fixes
- Codex Refactor - Recent optimizations (simulation gate, nonce refresh, gas hints)
- Integration Summary - Cross-reference of post-mortem findings and refactor work
Understanding the Bot:
- Architecture Overview - System design and components
- Execution Flow - Step-by-step how the bot works
- Key Concepts - Core strategies explained (Battering Ram Mode, pre-warming, dual-branch, etc.)
- Code Structure - Codebase organization and key functions
Historical Context:
- Master Synthesis - Complete timeline and analysis of bot development
Additional Resources:
- Documentation Index ⭐ - Master navigation hub for all documentation
- Repository Guidelines - Guidelines for AI agents working on this repository
- All guides, audits, and analysis reports are organized in the
docs/directory - Scripts Index - Complete index of utility scripts
- Data Files Index - Index of data files and their purposes
- Configuration Files Index - Index of configuration files
- Root Files Index - Index of root directory files
- Use
npm run analyze:mints:knownto fetch detailed gas/timing data for the 16 successful MiTeddy mints (outputsmint-insights.json). Update the tx list insidescripts/analyze-known-mints.tsas new slots land.
CRITICAL: Read this before running
-
Use a fresh hot wallet - Fund it ONLY with gas (BERA) and the two NFTs you're willing to sacrifice. NEVER paste your main wallet's private key into this script.
-
Verify contract details - The bot calls the MiTeddy contract directly (
0x111111111fd1a588bdb8254e3af1fc2fb0d9078a). Verify this address on Berascan before running. -
Test first - Run the bot with a pair of NFTs you can afford to lose in case of misconfiguration.
-
No guarantees - This bot is provided as-is. You are responsible for any losses.
npm installCopy the example environment file and fill in your details:
cp .env.example .envEdit .env and set:
PRIVATE_KEY- Your hot wallet's private key (0x-prefixed hex string)SACRIFICE_ADDR- MiTeddy contract address (default:0x111111111fd1a588bdb8254e3af1fc2fb0d9078a)TEDDY_ID- Your Steady Teddy token IDMIBERA_ID- Your Mibera token IDSAC_FUNCTION- Function signature (default:mint(uint256,uint256))
CRITICAL: The bot calls the MiTeddy contract directly, not the sacrifice contract. This was discovered after analysis of successful transactions. The default address is correct.
If you don't know your token IDs, automatically find them:
npm run find-tokensThis scans the blockchain for Steady Teddy and Mibera tokens owned by your wallet and displays the token IDs. Make sure your PRIVATE_KEY is set in .env before running.
For extreme competition with time-based spamming, get the exact unlock time from the website:
# Get timer from https://miteddy21e8.com/sacrifice (e.g., "02:25:50")
npm run calc-unlock "02:25:50"This calculates the exact unlock time and updates .env automatically. See EXACT_TIMING_SETUP.md for details.
For hands-free operation, use the auto-start script:
npm run auto-startThis will:
- Read
EXPECTED_UNLOCK_TIMEfrom.env - Wait until 10 minutes before unlock time
- Automatically start the bot at the right time
Note: Make sure you've run npm run calc-unlock first to set EXPECTED_UNLOCK_TIME.
Production (RBF Bot):
npm run start:rbfDry-run test (RBF Bot):
npm run start:rbf:dryLegacy Original Bot (DEPRECATED - not recommended):
npm start # Original bot (LEGACY)
npm start -- --dry-run # Original bot dry-run (LEGACY)Note: The keep-alive watchdog currently uses the Original bot (npm start). For RBF bot, run npm run start:rbf directly or modify keep-alive.ts to use the RBF bot.
When you are ready to go live, launch the TypeScript watchdog so crashes auto-restart within 5 seconds (max 10 retries). It executes npm start (Original bot) under the hood and streams the same logs:
npm run start:keep-alivenpm run start:rbf directly.
During startup you may see logs such as Skipping 2 HTTP RPC(s) for gas estimation (recent failures < 60s). - this is expected and means the new gas-estimation cooldown is avoiding endpoints that just failed so the pre-warm phase stays fast.
-
.envfilled withPRIVATE_KEY, token IDs, curatedRPCS_HTTP/RPCS_WS/RPCS_BROADCAST, and aggression knobs (PRE_WARM_TX=true,PRE_SIGN_GAS_LEVELS=true) -
npm run buildandnpm start -- --dry-runboth successful within the last hour -
npm run start:keep-aliveready in the launch terminal (or already running) - Latest log file (
logs/bot-<timestamp>_PST.log) monitored for pre-warm steps at T-10s, spam at T-25s, and cooldown messages for flaky RPCs
| Variable | Description | Example |
|---|---|---|
PRIVATE_KEY |
Hot wallet private key (0x-prefixed) | 0x1234... |
SACRIFICE_ADDR |
MiTeddy contract address (not sacrifice contract) | 0x111111111fd1a588bdb8254e3af1fc2fb0d9078a |
TEDDY_ID |
Steady Teddy token ID | 1234 |
MIBERA_ID |
Mibera token ID | 5678 |
| Variable | Default | Description |
|---|---|---|
SAC_FUNCTION |
mint(uint256,uint256) |
Function signature (actual function is mint, not sacrifice) |
SAC_FUNCTION_VIEW |
(none) | Optional view function for gating (e.g., isOpen()) |
PRIORITY_FEE_GWEI |
250 |
Base priority fee in gwei |
BASE_MULTIPLIER |
200.0 |
Base fee multiplier (RBF Bot: 200.0 = 5,000 Gwei base) |
RBF_BASE_GAS_MULTIPLIER |
200.0 |
Base multiplier for RBF pulses (RBF Bot) |
RBF_COMPOUND_BUMP |
1.05 |
5% compound increase per pulse (RBF Bot) |
RBF_MAX_GAS_MULTIPLIER |
1223.0 |
Maximum multiplier (30,580 Gwei) (RBF Bot) |
RBF_PULSES_PER_BLOCK |
20 |
Number of RBF pulses per 2-second block (RBF Bot) |
RBF_PULSE_INTERVAL_MS |
100 |
Milliseconds between pulses (RBF Bot) |
BUMP_INTERVAL_MS |
2500 |
Milliseconds between gas bumps |
BUMP_PCT |
0.20 |
Gas bump percentage (20%) |
MAX_BUMPS |
8 |
Maximum number of gas bumps |
SIMULATE_MS |
250 |
Polling interval in milliseconds |
RPCS |
(see .env.example) | Legacy comma-separated RPC URLs (falls back to HTTP/WS lists) |
RPCS_BROADCAST |
(defaults to RPCS/HTTP+WS lists) |
Comma-separated list of RPCs allowed to send nuclear (50x) transactions; only include nodes that accept >=12,500 gwei priority fees. |
PRIVATE_TX_RPC |
(none) | Private orderflow endpoint |
PRE_WARM_RPCS |
(defaults to RPCS_BROADCAST) |
Optional list of RPCs dedicated to pre-warm spam so the main nuclear relays stay fresh for T-0. |
PRE_SIGN_GAS_LEVELS |
true |
Pre-sign transactions at multiple gas levels |
RPC_HEALTH_CHECK |
true |
Monitor and auto-select fastest RPC |
PRE_WARM_TX |
true |
Pre-broadcast transaction when close to unlock |
MAX_PRIORITY_FEE_GWEI |
30580 |
Maximum priority fee cap (gwei) (RBF Bot: 30580 for 1,223x) |
BASE_MULTIPLIER (Legacy) |
50.0 |
[LEGACY] Original bot base multiplier (DEPRECATED) |
MAX_PRIORITY_FEE_GWEI (Legacy) |
12500 |
[LEGACY] Original bot max priority fee (DEPRECATED) |
MAX_FEE_PER_GAS_GWEI |
100000 |
Maximum fee per gas cap (gwei) (Battering Ram Mode: 100000) |
FEE_MAX_GWEI_CAP |
50000 |
Hard cap for all fees (gwei) (Battering Ram Mode: 50000) |
GAS_NUCLEAR_MODE |
true |
Enable nuclear gas mode (5x baseFee + 250 Gwei priority) |
UNLOCK_TIME_UNIT |
seconds |
Unit for remainingUnlockTime() return value (seconds or milliseconds) |
FAST_POLL_SECONDS |
3 |
Switch to fast polling when unlock time < N seconds |
FAST_POLL_MS |
100 |
Fast polling interval in milliseconds (10ms for last second) |
WS_ENABLED |
false |
Enable WebSocket transport for primary RPC (if available) |
BLOCK_SUBSCRIBE |
true |
Subscribe to new blocks via WebSocket for event-driven triggers |
NONCE_STRATEGY |
replace |
Nonce strategy: replace (same nonce, bump gas) or increment (new nonce per attempt) |
RPC_TIMEOUT_MS |
1000 |
Per-RPC request timeout in milliseconds (800ms when cancel-on-first-success) |
ULTRA_FAST_POLL_MS |
10 |
Ultra-fast polling interval when unlock time < 1 second |
MIN_BUMP_PCT |
0.12 |
Minimum gas bump percentage per replacement (12%) |
PRE_WARM_START_SECONDS |
300 |
Start pre-warming N seconds before unlock (Battering Ram Mode: 300) |
PRE_WARM_STEPS |
300:50.0;120:50.0;60:50.0;30:50.0;15:50.0;5:50.0;2:50.0;1:50.0 |
Pre-warm steps: "seconds:multiplier;seconds:multiplier" (Battering Ram Mode: permanent 50.0x) |
TIME_BASED_SPAM |
false |
[LEGACY] Spam based on timer (Original bot only - DISABLED) |
SPAM_START_SECONDS |
42 |
[LEGACY] Start spamming N seconds before expected unlock (Original bot only) |
SPAM_INTERVAL_MS |
25 |
[LEGACY] Milliseconds between spam transactions (Original bot only) |
SPAM_END_SECONDS |
42 |
[LEGACY] Continue spamming N seconds past expected unlock (Original bot only) |
EXPECTED_UNLOCK_TIME |
(none) | [LEGACY] Expected unlock time (Original bot only - NOT USED in RBF bot) |
TIME_OFFSET_MS |
-8000 |
Time offset adjustment in milliseconds (Battering Ram Mode: -8000ms buffer for early opening) |
NETWORK_LATENCY_MS |
0 |
Estimated network latency compensation in milliseconds (typically 50-200ms) |
- Startup & Lock - Acquires single-instance lock (
.miteddy.lock), validates config, connects to RPCs - Resume Check - If
.miteddy-state.jsonexists, checks pending transaction status before proceeding - Ownership Check - Verifies you own both NFTs
- Approvals - Sets
setApprovalForAllon both NFT contracts if needed - Block-Event Detection - Parallel WebSocket subscriptions monitor for window opening:
- Multiple RPCs subscribe to new blocks simultaneously
- On each block, checks
availableMintAmount()to detect window opening - 0-50ms detection latency (no time prediction needed)
- Window Opens - When
availableMintAmount() > 0:- Shotgun RBF Engine: Fires 20 pulses per 2-second block
- Gas Escalation: Starts at 200x (5,000 Gwei), escalates to 1,223x (30,580 Gwei)
- Compound Bumps: Each pulse increases gas by 5% (200x → 210x → 220.5x → ...)
- Multi-RPC Broadcast: Each pulse sent to 4 RPCs in parallel (80 total attempts per nonce)
- Receipt-Based Nonce: Waits for receipt before incrementing nonce
- Success - Logs transaction hash with telemetry, clears state, releases lock, and exits
Legacy Original Bot Flow (DEPRECATED - for reference only): 1-4. Same as RBF bot 5. Gate Detection - Uses view functions with polling [LEGACY] 6. Pre-warming - Starts 5 min early with 50.0x gas [LEGACY] 7. Time-based spam - 40 tx/sec starting 42s before unlock [LEGACY - DISABLED] 8. Transaction Fire - Dual-branch strategy at 50.0x/75.0x [LEGACY]
-
Run on a VPS - Deploy to a server close to your fastest Berachain RPC (often US-West works well).
-
Multiple RPCs - The bot broadcasts to all RPCs in parallel. Order them by measured latency in
.env. -
Split telemetry vs broadcast - Keep every RPC in
RPCS_HTTP/RPCS_WSfor reads, but list only nuclear-capable endpoints (>=12.5k gwei) inRPCS_BROADCAST. Fee-capped nodes automatically receive the 8.0x pre-signed track. -
Sacrifice cheap pre-warm RPCs - Point
PRE_WARM_RPCSat disposable/free endpoints so the 5-minute runway does not rate-limit your premium nuclear relays right before T-0. -
Higher Priority Fee - If you are losing races, increase
PRIORITY_FEE_GWEI(e.g., 100-200 gwei). For extreme competition, use1000gwei withBASE_MULTIPLIER=4.0and 6.0x escalation (up to 6,000 gwei priority fee at peak). -
Private Orderflow - If your RPC provider supports
eth_sendPrivateTransaction, setPRIVATE_TX_RPCto avoid wasting gas on reverts. -
Tune Polling - Lower
SIMULATE_MS(e.g., 100ms) for faster detection, but be mindful of RPC rate limits.
docs/audits/POST_MORTEM_2025-11-13_1111_WINDOW.md for detailed analysis of recent failures and fixes. Codex's refactor (2025-11-13) addresses nonce synchronization issues.
- Verify
TEDDY_IDandMIBERA_IDare correct - Confirm the wallet owns both NFTs on Berachain
- Check the token IDs on Berascan
- Fund your wallet with BERA for gas
- Consider a larger buffer for multiple gas bumps (e.g., 0.1-0.5 BERA)
- Another process is using your nonce
- Stop all bot instances
- Wait for pending transactions to clear or be included
- Restart the bot
- Note: Codex's refactor (2025-11-13) added nonce refresh before pre-warm to prevent this. If you still see this error, check
.miteddy-state.jsonfor stale nonce and verify on-chain nonce matches.
- This indicates a known bug - all RPCs were likely skipped (rate limited, blacklisted, or nonce errors)
- Check earlier logs for "nonce too low" errors
- Verify nonce in
.miteddy-state.jsonmatches on-chain nonce:npm run verify-contracts - See detailed analysis:
docs/audits/POST_MORTEM_2025-11-13_1111_WINDOW.md(Bug #1) - Workaround: Restart bot to refresh pre-signed transactions and nonce
- If
unlockTimejumps from small value (e.g., "2") to large value (e.g., "10799"): Window likely opened and closed between view checks - Consider enabling
TIME_BASED_SPAM=trueas fallback detection - See:
docs/audits/POST_MORTEM_2025-11-13_1111_WINDOW.mdfor detailed analysis
- The contract may gate by timestamp, merkle proof, or allowlist
- Verify your wallet is eligible (if applicable)
- Check that
SAC_FUNCTIONmatches the actual contract signature - Try setting
SAC_FUNCTION_VIEWif the contract exposes anisOpen()or similar function
- Network congestion or very high competition
- Increase
PRIORITY_FEE_GWEIandBASE_MULTIPLIER - Increase
MAX_BUMPSto allow more retries - Check RPC connectivity
- Verify RPC URLs are correct and accessible
- Some RPCs may have rate limits - reduce
SIMULATE_MSor remove slow RPCs - Try different public RPCs from Berachain docs
If the mint function differs from mint(uint256,uint256), update SAC_FUNCTION:
- Arrays:
sacrifice(uint256[] teddys, uint256[] miberas) - Different name:
mintWithBurn(uint256,uint256) - Multiple args:
sacrifice(uint256 teddyId, uint256 miberaId, bytes32 proof)
The bot builds a minimal ABI from the signature string automatically.
- Steady Teddys:
0x88888888A9361f15AAdBAca355A6B2938C6A674e - Mibera Maker:
0x6666397DFe9a8c469BF65dc744CB1C733416c420 - MiTeddy Contract (mint directly):
0x111111111fd1a588bdb8254e3af1fc2fb0d9078a(configurable via.envasSACRIFICE_ADDR)
- Network: Berachain Mainnet
- Chain ID: 80094
- Block Time: ~2 seconds
- Native Currency: BERA
Mints appear to follow a pattern (observed: 1:11:11 unlock time at 1:11 on 11/11). See MINT_SCHEDULE.md for details.
Recommendation:
- For view-based detection: Start the bot 5-10 minutes before expected unlock time
- For time-based spamming:
- Get timer from https://miteddy21e8.com/sacrifice (e.g., "02:25:50")
- Run
npm run calc-unlock "02:25:50"to calculate exact unlock time - Use
npm run auto-startto automatically start 10 minutes before unlock - See EXACT_TIMING_SETUP.md for extreme competition setup
Shotgun RBF Strategy - Block-event driven with escalating gas
# RBF BOT: Shotgun RBF configuration
PRIORITY_FEE_GWEI=250
BASE_MULTIPLIER=200.0
RBF_BASE_GAS_MULTIPLIER=200.0
RBF_COMPOUND_BUMP=1.05
RBF_MAX_GAS_MULTIPLIER=1223.0
RBF_PULSES_PER_BLOCK=20
RBF_PULSE_INTERVAL_MS=100
MAX_PRIORITY_FEE_GWEI=30580
# RPC Configuration
RPCS_HTTP=https://berachain-rpc.publicnode.com,https://rpc.berachain.com
RPCS_WS=wss://berachain-rpc.publicnode.com,wss://rpc.berachain.com
RPCS_BROADCAST=https://berachain-rpc.publicnode.com,https://rpc.berachain.comGas Strategy:
- First Pulse: 200x (5,000 Gwei priority fee)
- Escalation: 5% compound per pulse (200x → 210x → 220.5x → ...)
- Maximum: 1,223x (30,580 Gwei priority fee)
- Pulses per Block: 20 pulses per 2-second block
- Broadcast Attempts: 80 per nonce (20 pulses × 4 RPCs)
Performance:
- Detection: 0-50ms (Parallel WebSocket subscriptions)
- Fire Latency: 100-400ms from block to mempool
- Transaction Rate: 20 pulses per 2-second block
- Expected Success Rate: 50-60% in extreme competition
Expected Costs:
- Best case: ~0.1-0.2 BERA
- Typical: ~0.2-0.5 BERA
- Worst case: ~0.5-1.0 BERA (if many transactions included)
Battering Ram Mode - Maximum aggression from first transaction
# LEGACY: Original bot configuration (DEPRECATED)
BASE_MULTIPLIER=50.0
MAX_PRIORITY_FEE_GWEI=12500
TIME_BASED_SPAM=false # DISABLEDFor maximum speed, enable WebSocket block subscription:
WS_ENABLED=true
BLOCK_SUBSCRIBE=true
RPCS=wss://your-rpc.com,https://backup-rpc.comThis triggers view checks immediately on new blocks, reducing detection latency from ~50ms to < 10ms.
Build TypeScript:
npm run buildWatch mode:
npm run dev- RUNBOOK.md - Quick start guide, monitoring, troubleshooting
- ACCEPTANCE_TESTS.md - Test checklist with expected log patterns
MIT
This software is provided "as is" without warranty. Use at your own risk. The authors are not responsible for any losses incurred from using this bot.