Protocol Documentation
ERC-20 on Base with linear time-weighted reflections, automatic LP injection, and a tiered burn governor. No off-chain keepers. No minting after deployment. 1B fixed supply.
Contents
01
$FIRE is a reflection token on Base that runs entirely on-chain. No bots. No manual work. Everything executes automatically as a side effect of regular buys and sells.
Every buy and sell generates a 4% tax split into two functions:
2% → Liquidity Pool
Tax tokens accumulate in the contract. Once they hit a threshold, half is swapped to ETH and paired with the other half as Uniswap V2 liquidity. Deeper liquidity means less slippage for everyone.
2% → Holder Payouts
Tax tokens feed a pull-based payout accumulator. Your share is weighted by balance × time held. Hold longer, earn more per token. Payouts auto-sweep to your wallet on your next interaction.
On top of that, a tiered burn governor watches whale concentration. When enough big holders have held long enough, a slice of payouts gets permanently burned to 0xdEaD instead of paid out. This is the only burn mechanism in the contract.
02
| Name | FinancialIndependenceRetireEarly |
| Symbol | $FIRE |
| Decimals | 18 |
| Total Supply | 1,000,000,000 (fixed forever) |
| Mintable | No - _mint called once in constructor only |
| Network | Base (chainId 8453) |
| DEX | Uniswap V2 |
| Buy Tax | 4% (2% LP + 2% payouts) |
| Sell Tax | 4% (2% LP + 2% payouts) |
| Wallet-to-Wallet | 0% - tax only on AMM trades |
03
The tax hooks into the _updateoverride at the lowest level of the ERC-20 transfer. You can't dodge it by going directly through the pair or routing through another contract.
Buy/Sell detected (AMM pair involved): taxAmount = transfer * 4% lpTax = taxAmount / 2 (2% of transfer -> LP pool) payoutTax = taxAmount / 2 (2% of transfer -> holders) LP portion accumulates until threshold, then auto-injects Net amount delivered to buyer/seller
| Buy from Uniswap | 4% tax applied |
| Sell to Uniswap | 4% tax applied |
| Wallet → Wallet | No tax |
| Exempt address | No tax |
A one-way tradingOpen flag prevents all non-exempt transfers until the owner calls openTrading(). This is irreversible. Once open, it cannot be closed.
04
Payouts use a pull-based O(1) accumulator. A global rewardPerScore index advances every time payout tokens come in from a taxed trade. Your pending payouts are calculated from this index and auto-swept to your wallet whenever your address is involved in any transaction (buy, sell, transfer, or claim). No hourly loop. No gas scaling with holder count.
holdScore = balance * secondsHeld (capped at 2 years) Your share = your holdScore / total of all holdScores Pending = scoreSnapshot * (rewardPerScore - rewardPerScorePaid) / PRECISION
Your payout multiplier increases at fixed hold-time thresholds. The multiplier is not linear— it steps up at each tier.
| Base (0-29 days) | 1x |
| 30+ days | 1.5x |
| 60+ days | 2x |
| 90+ days | 2.5x |
| 120+ days | 3x (max) |
05
After holding for 15 days, you unlock a protected sell window. You can sell up to 20% of your bag without resetting your hold clock. Your multiplier stays intact.
Protected sell check: 1. holdStart must be > 0 (you're holding) 2. Must have held >= 15 days 3. Last protected sell must be >= 15 days ago (or never used) 4. Sell amount must be <= 20% of your balance Pass all four = clock preserved Fail any one = full clock reset
protectedSellAllowance(addr) and time until your next window via timeUntilNextWindow(addr).06
The 2% LP portion of every tax accumulates in the contract. Once it hits 0.1% of total supply (~1M tokens), the contract automatically injects liquidity:
LP injection (triggered automatically): 1. Take accumulated LP tokens 2. Swap half to ETH via Uniswap 3. Pair the other half + ETH as liquidity 4. LP tokens sent to contract owner Threshold: 1,000,000 FIRE (0.1% of supply)
This deepens the liquidity pool over time, reducing slippage for all traders. The injection runs inside the same transaction as a normal trade, so nobody needs to trigger it manually.
manualInjectLP() to force an injection if the threshold is met. The owner can call forceInjectLP() to inject at any accumulated amount.07
The burn governor is the only burn mechanism in the contract. It watches whale concentration and burns a percentage of payout tokens to 0xdEaD before they get distributed to holders.
When payout tokens come in from a taxed trade, the contract checks the current burn tier. If a tier is active, that percentage of the payout tokens gets sent to the dead address instead of entering the payout accumulator. The rest goes to holders as normal.
An address qualifies as a whale when it holds ≥ 100,000 tokens continuously. Any dip below this threshold fully resets the clock. Whales are tracked in real-time using O(1) band counters, not by iterating all holders.
| Tier | Whales required | Hold required | Payouts burned |
|---|---|---|---|
| 0 | < 100 | Any | 0% (inactive) |
| 1 | >= 100 | >= 15 days | 10% |
| 2 | >= 200 | >= 30 days | 20% |
| 3 | >= 500 | >= 45 days | 30% |
| 4 | >= 800 | >= 60 days | 40% |
Both conditions (whale count and hold duration) must be true at the same time. The contract checks from Tier 4 down and picks the highest qualifying tier. If nothing qualifies, burn rate is 0% and all payouts go to holders.
If whales sell, their clocks reset, the qualifying count falls, and the burn tier drops automatically. No owner action needed. Burned tokens are sent to 0xdEaD, permanently removing them from circulation.
manualCheckBurnTier() to force an immediate re-check.08
Every address has two independent clocks:
holdStart
When you began holding. Used for payout scoring and protected sell eligibility. Resets on any non-protected sell to AMM.
whaleStart
When you first crossed the 100k token threshold. Used by the burn governor. Resets if balance drops below 100k.
| Event | holdStart | whaleStart |
|---|---|---|
| First buy | Set to now | Set if >= 100k |
| Buy more (already holding) | Unchanged | Set if newly crosses 100k |
| Receive payouts | Unchanged | Set if crosses 100k |
| Protected sell (≤20%, 15d+) | Unchanged | Reset if < 100k |
| Normal sell to AMM | Reset to 0 | Reset if < 100k |
| Wallet transfer out (partial) | Unchanged | Reset if < 100k |
| Wallet transfer out (all) | Reset to 0 | Reset to 0 |
| secondsHeld(addr) | Seconds since holdStart (max 2 years) |
| holdScore(addr) | balance × secondsHeld |
| rewardShare(addr) | Your fraction of the payout pool (scaled to 1e18) |
| pendingReward(addr) | Tokens you can claim right now |
| protectedSellAllowance(addr) | Max tokens you can sell without clock reset |
| timeUntilNextWindow(addr) | Seconds until your next protected sell window |
09
| openTrading() | Enable public trading (irreversible) |
| setExempt(addr, bool) | Add/remove tax exemption |
| setAMMPair(addr, bool) | Register additional AMM pairs |
| forceInjectLP() | Inject LP at any accumulated amount |
| rescueETH(amount) | Recover stranded ETH |
| rescueTokens(token, amount) | Recover stuck tokens (can't touch LP-earmarked tokens) |
| claimRewards() | Manually claim your accrued payout tokens |
| manualInjectLP() | Trigger LP injection if threshold is met |
| manualCheckBurnTier() | Force burn tier re-evaluation |
10
Tax split math error
Original code double-divided by basis points, sending 98% of tax to LP and ~2% to payouts. Fixed to a clean 50/50 split.
rescueTokens always returned 0
Arithmetic identity made protected amount always equal contract balance. Fixed to correctly calculate rescuable portion.
11
12
| Uniswap V2 Router | 0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24 |
| WETH on Base | 0x4200000000000000000000000000000000000006 |
| $FIRE Token | 0xa7E1E8Ab7B7c93F9e3CeB10724843a4b74f5308C |
| Burn Address | 0x000000000000000000000000000000000000dEaD |
Disclaimer
$FIRE is an experimental onchain game. it is not a financial product, investment vehicle, or security. payouts are not guaranteed and depend entirely on trading volume. do not purchase with funds you cannot afford to lose.