Skip to Content
⚔ BattleMeme docs · early preview · expect rough edges
ProtocolArchitecture

Architecture

End-to-end picture of how the protocol is wired: contracts, off-chain services, and the data flow that turns a user click into an on-chain trade and an indexed UI update.

High-level overview

No VRF, no block.prevrandao. Round cadence is fully deterministic — once a battle commences, every cutoff is locked to a nextRoundAt timestamp the contract publishes.

Smart contract architecture

Contract responsibilities

ContractPurposeReference
TokenFactoryDeploys ERC-20, registers with hook, forwards 0.01 ETH for atomic creator pre-buy(planned)
BattleMemeTokenERC-20 (per memecoin), mint/burn gated to hook, freezable, immutable creator(planned)
BattleHookUniswap V4 hook (all 14 callbacks); state machine + laddered LP bootstrap + per-token accounting + fee sweep
BattleOrchestratorQueue, warmup, rounds, scoring (live getEthReserves), elimination, graduation orchestration
GraduationLPPer-winner LP custodian; deploys wide+wall LP at grad and locks in-protocol
ClaimManagerRegistry of loser → winner conversions; burn-and-transfer flow
VoucherManagerIndependent creator-promo tool: deposit ETH → off-chain signed / Merkle vouchers → on-chain redeem auto-buys token

No separate Treasury contract exists today. Both creation fees and swept LP fees route to factory.feeRecipient() (a single configurable EOA / multisig) and the token’s immutable creator.

Token state machine

See State machine for the per-state trading gates.

Key user journeys

Journey 1 — Create a token (with atomic creator pre-buy)

Net effect: creator pays 0.01 ETH, ends up holding the first-buy amount of tokens at the pool’s initial price. The 0.01 ETH lands in the LP — counted toward totalETHRaised and the 5 ETH queue threshold. Creator earns 0.3% of every swap forever.

Journey 2 — Trade during INIT

Journey 3 — Queue + Warmup

Journey 4 — Battle rounds (deterministic, ~19h)

Total: 4 × 1h + 3 × 5h = 19 hours (no trailing rest after R4)

runRound(battleId) is permissionless after nextRoundAt. It snapshots hook.getEthReserves(poolId) for each active token, sorts ascending, eliminates the bottom-K (where K comes from the cut table), and either schedules R+1 or finalizes.

Journey 5 — Graduation

Conversion ratio + cover formula:

ratio=winnerPriceQ96×1018loserPriceQ96winnerCover=loser.totalSupply×ratio1018\text{ratio} = \frac{\text{winnerPriceQ96} \times 10^{18}}{\text{loserPriceQ96}} \qquad \text{winnerCover} = \frac{\text{loser.totalSupply} \times \text{ratio}}{10^{18}}

Journey 6 — Loser holders claim

Claim deadline: none — forever-open window.

Random source

The protocol has no on-chain randomness. ROUND_GAP = TRADE_WINDOW + REST_WINDOW is a compile-time constant; UI reads nextRoundAt from getBattle(...) and drives its own countdown.

Chainlink VRF is NOT used. The only Chainlink integration is Automation (AutomationCompatibleInterface) for keeper-driven upkeep — and even that is just a polite fallback. Every entrypoint is permissionless.

Hook permissions

V4 hook permissions are encoded in the proxy address via CREATE2 + HookMiner. All 14 callbacks are enabled (mask 0x3FFF). Today only beforeInitialize / beforeAddLiquidity / beforeRemoveLiquidity / beforeSwap / afterSwap / unlockCallback are load-bearing; the rest are no-op pass-throughs.

Deployment order

1. ClaimManager 2. BattleOrchestrator 3. GraduationLP 4. BattleHook (CREATE2 with mined salt for permission mask 0x3FFF) 5. TokenFactory (constructor: hook, feeRecipient) 6. VoucherManager 7. Wire references: hook.set{Orchestrator,Factory,ClaimManager,GraduationLp}, orchestrator.set{Hook,ClaimManager,GraduationLp}, claimManager.setOrchestrator 8. Configure Chainlink Automation upkeep for BattleOrchestrator 9. Verify on Etherscan

See also: State machine, Tokenomics, Security, all contract references under /contracts/.