LIVE NOWTHE ONCHAIN UNICORNNO MINT BUTTONTHE TRADE IS THE INTERFACEONCHAIN FOREVERLIVE ON Robinhood ChainREBORN FROM A 2017 DOODLETHE ONCHAIN UNICORNNO MINT BUTTONTHE TRADE IS THE INTERFACEONCHAIN FOREVERLIVE ON Robinhood ChainREBORN FROM A 2017 DOODLETHE ONCHAIN UNICORNNO MINT BUTTONTHE TRADE IS THE INTERFACEONCHAIN FOREVERLIVE ON Robinhood ChainREBORN FROM A 2017 DOODLE

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

any transfer pool · router · wallet DN404Mirror ERC-721 for wallets & markets Funi · DN404 ERC-20 ledger + NFT sync 0xA65D…0FE3 SketchHook V4 hook: fee ratchet + reveals 0x3c4A…c4CC · flags 0x04CC SketchRenderer on-chain sprites → SVG + JSON transfer() mirrors ids fresh ids → ← writes seeds seed in tokenURI(id): one eth_call, zero infra
The hot path runs left to right: a transfer enters the token, the DN404 engine syncs NFTs in the same transaction, fresh ids queue at the hook, seeds are assigned during pool swaps, and the renderer draws the final art entirely from chain state.

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

Buyer Pool Funi (DN404) SketchHook swap: ETH in, exact input beforeSwap → fee = x·φ/10,000 held in ETH AMM executes → transfer(buyer, x) DN404: mint ⌊Δ⌋ NFTs recordPendingMints(ids) inline reveal: ≤30 seeds assigned, traits visible on receipt one transaction: fee charged · coin delivered · unicorns hatched · traits revealed
A canonical-pool buy, end to end. On foreign pools the first three arrows are identical and the reveal simply waits for the hook’s public queue (section 3).

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
1.0 2.0 3.0 1.7 · 1 NFT buy +0.4 → 2.1 · mints 1 🦄 2.1 · 2 NFTs sell −0.8 → 1.3 · burns 1 1.3 · 1 NFT the 2.0 threshold: crossing it in either direction moves an NFT, in the same transaction
Fractional balances always round down; only whole tokens have faces. Crossings mint and burn atomically inside the ERC-20 transfer itself.

The transfer algorithm

Every token movement executes this sequence atomically, inside the ERC-20 transfer:

  1. 1Debit sender, credit receiver. Standard ERC-20 accounting.
  2. 2Compute NFT deltas from the crossing formulas, respecting each side’s skip flag.
  3. 3Burn surplus ids from the sender into the FIFO burn pool.
  4. 4Mint deficit ids to the receiver, recycling burned ids first.
  5. 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 classNFT syncReason
Externally owned walletoncollectors receive NFTs on receipt
Any contract (extcodesize > 0)off by defaultpools, routers, and vaults hold clean ERC-20 balance: no NFT spam, no gas explosion inside swaps
The paired pool and the hookoff, explicitbelt and suspenders on the hot path
Everyone, while nftMintingEnabled = falseofftoken-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.

buyer swaps on any pool: V2/V3/V4 FUNI.transfer() the only way to move it DN404 mints NFTs same transaction ids queue at hook seeds next batch
A buy on a foreign pool with no hook. The mint is universal and instant; only the trait reveal waits for the hook’s queue, which is public and permissionless.
VenueMint on buyBurn on sellReveal latency
Canonical V4 pool (SketchHook)same txsame txsame tx (inline batch, up to 30 ids)
Independent V4 / V3 / V2 poolsame txsame txnext canonical swap, or permissionless requestReveal()
Direct wallet transfersame txsame txas above
CEX custodyon withdrawal to self-custodyon depositas 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

a burned id never keeps its traits; every mint is a fresh draw minted revealPending seed seeded art fixed sell burned reminted: seed RESET → fresh roll
Without the reset, an attacker could watch rare ids enter the burn pool and reacquire them with traits intact, turning the burn pool into a rarity vending machine. With it, the only way to keep a rare is to keep the whole tokens backing it.

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:

TraitRectanglesRenders in one call
rainbow1,576yes
car818yes
typical piece200–500yes

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):

OperationGasNote
Plain ERC-20 transfer (no NFT crossing)standardfractional moves are cheap
Each NFT minted on a whole-token crossing~35,000dominates large buys
200-token buy (200 NFTs mint)~7M of 25Mlaunch tooling sizes buy gas limits for exactly this
Inline reveal batch≤ 30 ids/callkeeps any single tx gas-safe
tokenJSON render, heaviest pieceread-onlyeth_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

ActorIncentive / attackWhat the code does about it
Buyerbest execution + the hatchplain AMM fill; NFTs mint atomically in the same transaction; there is no state where the coin arrived and the collection did not
Sellerexit without losing the rarescan’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-pickerwatch rare ids enter the burn pool, reacquire them with traits intactthe 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 predictortime buys against prevrandao to farm raresacknowledged 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 venuelist FUNI and strip its mechanicsimpossible 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 grieferforce an unboundedly expensive transactiontwo 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 hookre-enter during the reveal auto-firededicated reentrancy slot on the reveal path (sketch-mirror-hook-v2.non-reentrant)
Artist roleswap the renderer maliciouslyscope 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 mintingHook can 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

ItemValue
ChainRobinhood Chain, id 4663
CompilerSolidity 0.8.26, via-IR, optimizer runs 1, Cancun EVM
Funi token0xA65D0267c8637fcC46fF91E48De766721c750FE3
Mirror0xb77d080cc45c8fd839bb568e22e3be2756ffdf6e
SketchHook0x3c4A0541624e3f9A69481408637be60152E9c4CC (CREATE2-mined, flags 0x04CC)
Renderer (active)0xC79668De06d77B4DAcE926ada22D7e8b43860bc9 (upgraded live from 0x4871…Fe2c)
Launched2026-08-16, minting on from first buy
Live state at publication9,208 NFTs · reveal queue 0 · burn pool on
The honest fine print. All figures verified on chain at publication and subject to change as the system runs. Inline reveal randomness is block-derived and deliberately gates nothing of economic value until VRF mode is armed. The protocol has not yet been audited. Funi is an independent project built on Robinhood Chain and is not affiliated with, endorsed by, or operated by Robinhood. Nothing here is financial advice.