Technical whitepaper · v2 · chain 4663
The FUNI Engine
FUNI is a fixed-supply asset (10,000 tokens, ever) that is simultaneously an ERC-20 and an ERC-721 collection. The fusion lives in the token’s transfer layer itself, so any pool, router, or wallet that moves the coin also drives the collection: no integration required, no way to bypass it. This paper specifies the mechanics, the formulas, the gas envelope, and the security posture, all backed by live production data.
Supply
10,000
fixed, 18 decimals
NFTs live
9,208
of 10,000 possible
Reveal queue
0
nothing stranded
Art
On-chain
full collection, one call
1 · Architecture
Four contracts, one hot path
The token holds two privileged references, both set once: mintingHook (immutable; the only address permitted to write trait seeds) and renderer (swappable by the artist role only, which allowed one live art upgrade already). The mirror is deployed by the token’s own constructor, so the pair is born atomically and cannot be mismatched.
One canonical buy, end to end
2 · The DN404 engine
Whole tokens have faces
Let B(a) be the ERC-20 balance of address a and U = 10^18 one whole token. For every address not exempted by the skip rule, the engine maintains:
N(a) = floor(B(a) / U) NFT count tracks whole tokens invariant: mirror.balanceOf(a) ≤ base.balanceOf(a) / U never over-minted every transfer of amount x from a to b: burn(a): max(0, N_before(a) - floor((B(a) - x)/U)) ids leave a mint(b): max(0, floor((B(b) + x)/U) - N_before(b)) ids arrive at b
The transfer algorithm
Every token movement executes this sequence atomically, inside the ERC-20 transfer:
- 1Debit sender, credit receiver. Standard ERC-20 accounting.
- 2Compute NFT deltas from the crossing formulas, respecting each side’s skip flag.
- 3Burn surplus ids from the sender into the FIFO burn pool.
- 4Mint deficit ids to the receiver, recycling burned ids first.
- 5Enqueue for reveal. Collect freshly minted ids, reset any stale trait seed, and push the batch to the hook via
recordPendingMints.
A deliberate design choice
Step 5 is not wrapped in try/catch. A failure reverts the entire swap, because a minted NFT that never entered the reveal queue would be permanently unrevealable. Loud failure is chosen over silent corruption.
The skip policy
| Address class | NFT sync | Reason |
|---|---|---|
| Externally owned wallet | on | collectors receive NFTs on receipt |
Any contract (extcodesize > 0) | off by default | pools, routers, and vaults hold clean ERC-20 balance: no NFT spam, no gas explosion inside swaps |
| The paired pool and the hook | off, explicit | belt and suspenders on the hot path |
Everyone, while nftMintingEnabled = false | off | token-only launch phase; flipped on at launch |
The contract skip is what makes FUNI safe in any AMM: a pool holding 4,000 FUNI holds a plain balance, not 4,000 NFTs. The NFTs materialize only when tokens reach a wallet. And with the burn pool enabled, burned ids recycle first-in-first-out, keeping the live id range compact.
3 · Venue independence
The engine travels with the token
The claim: create any additional market for FUNI, on any protocol version, and the NFT mechanics continue to work, unchanged, with zero cooperation from that market. The argument is structural: the entire NFT engine lives inside the token’s transfer function, and any venue that delivers tokens must call transfer or transferFrom. There is no third way to move an ERC-20.
| Venue | Mint on buy | Burn on sell | Reveal latency |
|---|---|---|---|
| Canonical V4 pool (SketchHook) | same tx | same tx | same tx (inline batch, up to 30 ids) |
| Independent V4 / V3 / V2 pool | same tx | same tx | next canonical swap, or permissionless requestReveal() |
| Direct wallet transfer | same tx | same tx | as above |
| CEX custody | on withdrawal to self-custody | on deposit | as above |
The honest nuance is the reveal-latency column: minting and revealing are separate steps. A foreign-venue mint shows placeholder art until the queue drains, and the queue is public and permissionless (requestReveal(), thirty ids per call, callable by anyone). Nothing can strand: current queue depth is zero, and after the largest mint waves a single script pass cleared thousands of ids.
The strategic consequence
As liquidity fragments across pool versions over the chain’s life, projects whose tokenomics live inside one pool’s hook lose them the moment volume migrates. FUNI’s engine travels with the token. No venue can strip the coin of its collection.
4 · Trait lifecycle
The anti-cherry-pick rule
Verified live · id 6023
Minted as a mythic on 2026-08-10 at 00:04. Burned the same day at 14:16 when its holder moved whole tokens. Reminted 2026-08-11 at 19:42 to a different wallet, this time as a common. The mythic art existed for fourteen hours and is gone. This is by design, and it is the strongest holding incentive in the system.
5 · The renderer
The entire collection lives on chain
The renderer stores the full sprite sheet in packed contract storage and assembles art on demand:
canvas: 128 × 128 rect: 5 bytes = (x, y, w, h, shadeIdx) palettes: 36 body colors, 6 backgrounds layer modes: RANDOM per-NFT rolled color; shadeIdx picks dark/mid/light FIXED layer ships its own "#rrggbb" palette BORROW_BODY reuses the rolled body color (legs)
tokenURI(id) computes traits from the seed, walks the layers, and emits base64 SVG plus JSON in a single eth_call. The naive approach (nested string concatenation) is quadratic in memory and would revert on heavy pieces; the renderer uses a dynamic buffer for O(n) assembly, so the heaviest traits render in one call:
| Trait | Rectangles | Renders in one call |
|---|---|---|
| rainbow | 1,576 | yes |
| car | 818 | yes |
| typical piece | 200–500 | yes |
No server. No IPFS pin. No metadata rot. If the chain exists, the art exists, and any marketplace that calls tokenURI gets the full piece with zero infrastructure. The renderer address is swappable by the artist role only, exercised once in production to upgrade art quality without touching ownership or seeds.
6 · Gas envelope
Bounded by design, measured in production
Measured on chain 4663 (gas price about 0.02 gwei, so dollar costs are negligible; the engineering constraint is block gas, not price):
| Operation | Gas | Note |
|---|---|---|
| Plain ERC-20 transfer (no NFT crossing) | standard | fractional moves are cheap |
| Each NFT minted on a whole-token crossing | ~35,000 | dominates large buys |
| 200-token buy (200 NFTs mint) | ~7M of 25M | launch tooling sizes buy gas limits for exactly this |
| Inline reveal batch | ≤ 30 ids/call | keeps any single tx gas-safe |
tokenJSON render, heaviest piece | read-only | eth_call; users pay nothing |
The 30-id reveal cap plus the contract-skip rule are the two governors that keep worst-case transactions bounded no matter how large a buy is or how much liquidity a pool holds.
7 · Game theory
Every actor, every attack, the defense in code
| Actor | Incentive / attack | What the code does about it |
|---|---|---|
| Buyer | best execution + the hatch | plain AMM fill; NFTs mint atomically in the same transaction; there is no state where the coin arrived and the collection did not |
| Seller | exit without losing the rares | can’t be done selectively: crossings burn FIFO from the wallet’s ids. Keeping a rare means keeping the whole tokens backing it, so the holding incentive is structural |
| Burn-pool cherry-picker | watch rare ids enter the burn pool, reacquire them with traits intact | the remint resets the seed and re-enqueues a fresh reveal, so every mint is a fresh draw (verified live, id 6023: mythic → burned → reminted common) |
| Seed predictor | time buys against prevrandao to farm rares | acknowledged openly: inline randomness is block-derived and influenceable at the margin. Therefore rarity gates nothing of economic value until VRF mode (built, two-day timelock) is armed. The attack has status to win, not money |
| Foreign venue | list FUNI and strip its mechanics | impossible by construction: the engine lives in transfer itself. The worst a hostile venue can do is what any venue does: move tokens, which runs exactly the engine in section 2 |
| Gas griefer | force an unboundedly expensive transaction | two governors: the contract-skip rule (pools hold plain balances, never thousands of NFTs) and the 30-id reveal cap per call |
| Malicious token wired into the hook | re-enter during the reveal auto-fire | dedicated reentrancy slot on the reveal path (sketch-mirror-hook-v2.non-reentrant) |
| Artist role | swap the renderer maliciously | scope is art only; ownership, balances, and seeds are untouchable from that role; exercised once in production for a quality upgrade |
8 · Security posture
What can and cannot happen
- Reveal integrity. Only the immutable
mintingHookcan write seeds. Mint-without-enqueue is impossible by construction (loud revert). Stale seeds cannot survive a remint. Inline randomness is predictable and therefore, by policy, gates nothing until VRF is enabled behind its timelock. - Reentrancy. The hook’s reveal path carries a dedicated guard; the token’s transfer engine performs effects before external interaction with the hook.
- Venue risk. Foreign pools cannot corrupt state: the worst a hostile venue can do is what any venue does, move tokens, which triggers exactly the engine in section 2. Contract skip caps their footprint at plain balances.
- Governance surface. Owner powers are narrow and enumerable: flip minting, flip the burn pool, swap the renderer (artist role, art only), and arm VRF behind a two-day public delay.
9 · Deployment record
Everything, verifiable
| Item | Value |
|---|---|
| Chain | Robinhood Chain, id 4663 |
| Compiler | Solidity 0.8.26, via-IR, optimizer runs 1, Cancun EVM |
| Funi token | 0xA65D0267c8637fcC46fF91E48De766721c750FE3 |
| Mirror | 0xb77d080cc45c8fd839bb568e22e3be2756ffdf6e |
| SketchHook | 0x3c4A0541624e3f9A69481408637be60152E9c4CC (CREATE2-mined, flags 0x04CC) |
| Renderer (active) | 0xC79668De06d77B4DAcE926ada22D7e8b43860bc9 (upgraded live from 0x4871…Fe2c) |
| Launched | 2026-08-16, minting on from first buy |
| Live state at publication | 9,208 NFTs · reveal queue 0 · burn pool on |