Pokédex entry
Everything about Pokémoni in one page. No token-sale language, just how the thing works.
What it is
Pokémoni ($MONI) is an ERC-20i: a normal ERC-20 token whose contract can also draw a picture for any balance. There is no separate NFT and nothing to mint. Hold whole tokens (we call them EXP) and the contract will render a Pokémon for your wallet whenever anyone asks it to. Sell them and the picture changes. The art is a pure function of two numbers, your whole-token balance and your address, computed inside the contract at read time. Nothing is stored off-chain, not even the image.
It runs on Robinhood Chain, an Arbitrum-based L2 that settles to Ethereum and uses ETH for gas.
Pokémoni is a fan-made art project. It is not affiliated with, endorsed by or connected to Nintendo, Game Freak or The Pokémon Company. Every creature is procedurally drawn by the contract; none is an existing character.
The Pokémon
Every render is a vector scene the contract writes as SVG: a gradient sky from the line's palette, a sun, a moon with stars, or a low dusk sun; a habitat (meadow, forest hills with pines, or a lake); one to three clouds, sometimes a flock; and the Pokémon itself, standing on the ground with a soft shadow. The seed picks one of four Kanto evolution lines, each drawn from scratch as a vector sticker and stored in its own contract: Bulbasaur → Ivysaur → Venusaur, Charmander → Charmeleon → Charizard, Squirtle → Wartortle → Blastoise and Pichu → Pikachu → Raichu. Time of day, habitat, clouds and flock come from the seed too, so two trainers holding the same amount get different scenes. In a browser the scene moves: the Pokémon bobs and blinks, flames flicker, clouds drift, stars twinkle.
The one thing your balance controls directly is the level. Under 21k EXP the wallet holds an Egg, coloured after the line it will hatch into. At 21k it hatches into the basic form, and each band after that raises its level and grows it. From 1.05M it evolves into the first evolution, from 2.1M it reaches its final form and is shiny: the alternate colouring, sparkles and the level 5 sky in Robinhood green. That is the whole idea: hold and it levels up, sell and it drops back.
The line is rolled from your balance and address together, so the Pokédex meta reports the species and its national dex number for every render, and a wallet that levels up may switch line on the way. Only the level is yours to control.
Trainer levels
Eleven steps. Thresholds are in whole tokens. Steps 1 to 10 come in pairs per level; the second of each pair starts halfway through the level's band, so the Pokémon grows more often than the palette changes.
| step | from | level | stage | palette level |
|---|---|---|---|---|
| 0 | < 21k MONI | Egg | Egg | 0 |
| 1 | 21k MONI | Lv. 5 | Basic | 1 |
| 2 | 273k MONI | Lv. 10 | Basic | 1 |
| 3 | 525k MONI | Lv. 16 | Basic | 2 |
| 4 | 787k MONI | Lv. 22 | Basic | 2 |
| 5 | 1.05M MONI | Lv. 30 | Stage 1 | 3 |
| 6 | 1.31M MONI | Lv. 36 | Stage 1 | 3 |
| 7 | 1.57M MONI | Lv. 45 | Stage 1 | 4 |
| 8 | 1.84M MONI | Lv. 55 | Stage 1 | 4 |
| 9 | 2.1M MONI | Lv. 70 | Final form · shiny | 5 |
| 10 | 2.62M MONI | Lv. 100 | Final form · shiny | 5 |
Palette levels follow the ERC-20i convention: 21k, 525k, 1.05M, 1.575M and 2.1M tokens, out of a fixed supply of 210M. Level 5 has its own palettes in Robinhood green.
Partner and caught
Your live balance is your partner: one Pokémon that redraws on every transfer in or out. The seed is the whole-token part of your balance; the fraction below one token is ignored.
Send your exact whole partner (the whole-token amount, no more, no less) to another trainer and it does not merge into their balance as loose tokens. It is traded: it arrives as a caught Pokémon, a fixed piece that keeps your address in its seed, listed separately from their own partner. They can trade it on the same way. If they sell any part of it, the piece is released back into ordinary tokens.
- Receiving tokens gives your partner EXP. Sending less than the whole partner takes EXP away.
- Caught Pokémon are enumerable per trainer. The trainer card shows them under the partner.
- Burning (sending to the zero address) reduces supply and your partner's EXP like any sell.
The party
getPartySvg(address) draws everything a trainer holds as one scene: the partner and every caught Pokémon standing together under that trainer's own sky, with a Poké Ball for each of the six party slots. Up to six members are drawn; getPartyMeta(address) carries the true count. Like the Pokémon, it is computed inside the contract at read time and cannot be edited.
The party is the collecting game. The only way to add a Pokémon to yours is to be traded another trainer's exact whole balance, so full parties mean other trainers chose to hand you their Pokémon. The site ranks the fullest parties under the Parties tab.
Launch rules
Trading starts when the deployer calls launch(pool) with the DEX pool address. Before that, only transfers to or from the deployer are possible. After launch a per-buy cap ramps from 0.05% of supply by 0.005% per second, reaching the full supply after about five and a half hours. There are no taxes, no blacklist, no pause, and no way to change the art after deployment.
Contract
Not deployed yet. This page updates with the address at launch.
Seven contracts: the token, the generator, the habitat renderer and one sprite contract per evolution line. The generator holds their addresses as immutables; nothing can be swapped after deployment.
The read surface that the site and the bots use:
| function | returns |
|---|---|
partnerOf(address) | the trainer's dynamic seed (seed, extra) |
caughtCount(address) | number of caught Pokémon |
caughtOfOwnerByIndex(address, i) | the i-th caught Pokémon's seed |
getSvg((seed, extra)) | the image, as SVG text |
getMeta((seed, extra)) | JSON with level, stage, species, dex number, line, type, time, habitat, clouds, birds, shiny, colours |
getPokemon((seed, extra)) | the same traits as a struct, for native rendering |
getPartySvg(address), getPartyMeta(address), seedsOf(address) | the trainer's whole set as one scene, its counts, and the raw seeds |
trainersCount(), getTrainersList(from, n) | enumerate trainers |
partnersTotalCount(), caughtTotalCount() | totals |
extra is keccak256(abi.encode(originalTrainer)). For a partner that is the holder; for a caught Pokémon it stays the address of whoever first held those tokens as a partner.
Read it yourself
With Foundry's cast against any RPC:
# your partner's seed
cast call $MONI "partnerOf(address)((uint256,uint256))" $YOU --rpc-url $RPC
# the image
cast call $MONI "getSvg((uint256,uint256))(string)" "(800000,$EXTRA)" --rpc-url $RPC > pokemon.svgRenders are heavy views. Call getSvg once per piece rather than through a multicall, or the node's per-call gas cap will trip.
FAQ
Do I need to mint?
No. Holding at least one whole token is the mint. Under 21k it is an Egg, but it is yours.
Why did my Pokémon change?
Your balance changed. The image is recomputed from the current balance every time it is read.
Can I pick my Pokémon?
No. The line comes from your address and your balance together. Every step is a new roll, so a wallet that levels up may change line on the way. What you control is the level: Egg, basic form, first evolution, final form, shiny.
Is this official?
No. Pokémoni is fan art. It is not affiliated with, endorsed by or connected to Nintendo, Game Freak or The Pokémon Company.
Can the team change the art?
No. There are no setters. The renderer and palettes are fixed in the deployed bytecode.
Where is the image stored?
Nowhere. It is produced on demand by the contract. This site, the share cards and the bots all call the same function.
How do I trade someone my Pokémon?
Send them your exact whole-token balance. It arrives as a caught Pokémon. See partner and caught.