~/goonerlabs
← All case studies
ethers v6HardhatOpenZeppelin v5

ChainBois — an on-chain play-to-earn economy on Avalanche

Role: Backend + smart-contract developer and the testnet-faucet frontend (sole author, 73 backend + 12 faucet-FE commits) · Client: 3BUX LLC · Built for: Avalanche Build Games Hackathon 2026 Stack: Node.js · Express · ethers v6 · Hardhat 2.28.6 · OpenZeppelin v5.6 · Solidity 0.8.24 · MongoDB (21 models) · Redis/Bull · Firebase RTDB · Socket.io · PM2 (cluster) On-chain (Fuji testnet, verifiable): $BATTLE ERC20Capped · ChainBoisNFT ERC-721 · WeaponNFT ERC-721

The problem

ChainBois is a play-to-earn third-person shooter: players own NFT soldiers and weapons, earn a capped $BATTLE token through gameplay, level characters up on-chain, and compete in tournaments for real prizes. This was the team's first full EVM project, and it had three hard requirements:

  1. A Unity game must not talk to the blockchain. Game developers can't be expected to implement wallet signing, gas handling, or contract calls inside Unity.
  2. The economy must not inflate. A P2E token that can be minted freely dies. $BATTLE had to be provably finite and self-regulating.
  3. No player should ever pay gas to play, and no purchase should ever half-complete. On-chain failures are normal; the UX can't expose them.

Architecture

Design principle — backend-heavy blockchain. Every on-chain operation runs server-side via ethers. The game and frontend never sign contract calls. The backend manages five AES-256-encrypted platform wallets (deployer, NFT store, weapon store, rewards, prize pool) and pays all transfer fees, so players experience a gasless game while the platform keeps custody and control of the trust boundary.

Firebase as the game bridge. Unity reads characters, weapons, and level from Firebase Realtime DB — never the API. The backend verifies on-chain ownership, writes the result to Firebase, polls game scores back every 5 minutes, runs anti-cheat, and persists to MongoDB. The tradeoff: I accept a thin eventual-consistency window (the 5-minute sync) in exchange for completely decoupling the game client from both the API and the chain.

The hardest decision: a self-regulating deflationary economy

$BATTLE is an ERC20Capped token with a fixed 10M supply — no new tokens can ever be minted. That guarantee is the whole point, but it creates a problem: if rewards are fixed and the pool drains, the economy stalls. So I built a dynamic tokenomics engine that reads the rewards-pool health every 6 hours and adjusts conversion rate and burn rate by tier:

Health tierPool %$BATTLE conversionBurn rate
ABUNDANT75%+1.0×50%
HEALTHY50–75%0.75×40%
MODERATE30–50%0.5×30%
SCARCE15–30%0.3×20%
CRITICAL<15%0.15×10%

Weapon-purchase revenue is periodically swept: part is burned permanently, the rest recycled to the rewards pool. The economy throttles itself toward solvency instead of relying on a fixed emission schedule I'd have to hand-tune.

What I designed for failure

  • Purchase failsafe — purchases use atomic DB claims so two buyers can't be sold the same NFT; a cron job detects stuck purchases every 5 minutes and auto-recovers or refunds.
  • Failed-payout retries — tournament prize payouts that fail on-chain are retried on a schedule rather than silently lost.
  • Wallet health — an hourly job monitors all platform wallet balances and auto-tops-up low-gas wallets from the deployer, with Discord alerts when the deployer itself runs low.
  • Platform audit — a daily solvency check reconciles on-chain ownership against the database and flags discrepancies.
  • Anti-cheat — score plausibility checks, velocity limits, daily earning caps, threat scoring, and a ban system protect competitive integrity before scores convert to tokens.

All of this is covered by a 258-test suite, with 10 cron jobs running the automated economy (score sync, tournaments, purchase failsafe, failed-payout retry, tokenomics sweep, wallet health, platform audit, inventory replenish, and more).

Results

  • Shipped a full EVM backend — 3 deployed contracts, 21 models, 10 cron workers, 258 tests — for a hackathon, from scratch.
  • Demonstrated ERC20Capped + dual ERC-721 + EIP-4906 dynamic metadata, server-side custody, and a self-balancing token economy.
  • Contracts are live and independently verifiable on Avalanche Fuji (see links above); mainnet is on the roadmap.
  • Built the testnet faucet frontend too (vanilla JS, ethers v6, EIP-6963 multi-wallet discovery + EIP-3085 auto-add-Fuji) — a one-click "starter pack" (2 NFTs + 8 weapons + 1,000 $BATTLE per wallet, one-per-wallet enforced) — so ChainBois is a full-stack proof I own contract → API → UI.

What this demonstrates

EVM fluency end-to-end on a real deadline: smart-contract design with OpenZeppelin v5, server-side transaction orchestration with ethers v6, a non-trivial tokenomics system, and the failure-handling (atomic claims, retries, auto-funding, audits) that separates a payable on-chain economy from a demo.