Inspired by Heraldia ↗

MANDALIA

Generative · Vector · 100% Onchain · Ethereum Mainnet

10,000 deterministic radial compositions. State-derived from a bytes32 seed plus a uint16 transfer counter. SVG is synthesized inside tokenURI() on every eth_call — no IPFS, no metadata server, no off-chain compute, no proxy. Renderer is upgradeable; storage is immutable.

Supply
10,000
Price
0.0001
Per Wallet
25
Chain
ETH L1
0 / 10,000 MINTED 0.00%
Max 25 per tx & per wallet · ERC-721 · ERC-2981 · ERC-4906 · 5% Royalties · CC0
* * *

Your wallet is the artisan.
Every transfer is a new ring.

Pure Solidity. No IPFS. No servers.
The code is the art.

Once deployed, immutable.
The mandala never stops growing.

— Mandalia, MMXXVI
* * *

Lineage

Built in the lineage of Heraldia.

Heraldia pioneered fully onchain SVG evolution on Ethereum mainnet — a 10,000-piece collection where each token mutates on every transfer. Mandalia is its spiritual successor. Same chain. Same standard. Same conviction in permanence.

Heraldia holders receive tiered free claims as recognition of the path they laid:

1–4 held → 1 free · 5–9 held → 3 free · 10+ held → 10 free

Eligibility verified via Merkle snapshot taken before launch. No live-balance gaming.

* * *

Live Preview

Click any cell to regenerate. Output identical to what the deployed renderer produces — same PRNG, same palettes, same pipeline.

12 random samples
* * *

Top 10 Holders

Live ranking from chain state. Refreshes every minute.

RankWalletHolding
Loading…
* * *

Transfer Simulator

Input a token ID to see how it would mutate after 50 more transfers. Current state vs simulated future, rendered live from the contract.

Current state
CURRENT
After 50 transfers
AFTER 50 TRANSFERS
* * *

How It Works

Three states. One contract. Forever onchain.

01
Mint

A 32-byte seed is derived from keccak256(prevrandao, sender, tokenId) at mint. The seed is the genome — palette, symmetry, motif family, remate, bindu. All determined. All immutable.

02
Transfer

The contract increments a per-token counter on every transfer. EIP-4906 is emitted; marketplaces refresh the rendered image. No oracle, no off-chain trigger.

03
Evolve

Eight logarithmic stages. Density grows, accent bands appear, satellite constellations bloom. The piece remembers every owner. At stage seven, it reaches its final form.

* * *

Architecture

Three-contract topology. Renderer is mutable until locked. Storage is single-purpose.

       ┌──────────────────────────────┐
       │  NFT.sol  (ERC-721/2981/4906)│ ───┐
       │  mint · transfer hook        │   │  delegates tokenURI
       │  tokenURI → delegate         │   ↓
       └──────────────┬───────────────┘   ┌──────────────────────────┐
                      │ writes           │  Renderer.sol            │
                      │ seed + tx counter  │  render(seed, txCount)   │
                                        │  Solady DynamicBuffer    │
       ┌──────────────────────────────┐  │  asm hot paths · cos LUT │
       │  Storage.sol                 │ ←─┤  data:image SVG URI      │
       │  bytes32 seed + uint16 txc   │  └──────────────────────────┘
       └──────────────────────────────┘
      

NFT Contract

Standard ERC-721 with _update() override emitting MetadataUpdate per EIP-4906 and incrementing the per-token transfer counter via the storage contract.

Renderer Contract

Pure view contract. Single entry render(bytes32, uint16). Solady DynamicBuffer for sub-linear concat. Critical paths inlined in assembly.

Storage Contract

Two mappings: seedOf(uint256) and transferCountOf(uint256). Write authorization restricted to the NFT contract — set at deploy, immutable.

Why Split?

Renderer is heavy (~20 KB bytecode). Bundling would push past EIP-170 24 KB limit. Splitting also enables renderer patches via setRenderer() until locked.

Rendering

Deterministic SVG synthesis from a 32-byte seed. Output is data:application/json;base64,<…> with embedded SVG.

// NFT.sol
function tokenURI(uint256 id) external view override returns (string memory) {
    bytes32 seed = storage_.seedOf(id);
    uint16  txc  = storage_.transferCountOf(id);
    return renderer.render(seed, txc, id);
}

PRNG

Mulberry32 ported to Solidity (uint32 arithmetic). Sub-seeded per ring. Bit-exact match with JS reference.

SVG Construction

Direct byte concat via Solady's DynamicBuffer — preallocates 2 KB, doubles on demand. Avoids quadratic native concat cost.

Symmetry via Transforms

SVG transform="rotate()" instead of trig in Solidity. Each motif drawn once at (0,−r) and rotated N times.

Determinism

No block.timestamp, no blockhash. Identical bytes from genesis until heat death. keccak256(render(seed, txc)) is constant per input.

Evolution

Transfer hook increments a counter; counter feeds back into the renderer. Eight visual stages on a log curve — denser motifs, accent bands, satellite constellations.

StageTransfersVisual Additions
00Genesis composition
1–31–40Motif density × 2–4 · inner slot echo lines
441–80Saturated density · 4 echo lines · 40% stroke weight
581–200+ thick inter-slot separators
6201–340+ satellite constellations between rings
7341++ alternate-ring accent banding · final form

Traits

11 traits — 8 DNA (immutable) and 3 state-derived (mutable on transfer).

Symmetry
DNA · 5 weighted
12 (25%) · 16 (30%) · 20 (25%) · 24 (15%) · 32 (5% legendary) axes
Palette
DNA · 12 curated
Tibet · Persia · Alhambra · Sumi-e · Stained Glass · Bauhaus · Onyx · Coral · Forest · Lapis · Crimson · Slate
Family
DNA · 6 values
Geometric · Organic · Calligraphic · Dotted · Linear · Interwoven
Bindu (center)
DNA · 8 values
Disk · Star · Eye · Hexagram · Triple · Rays · Void · Lotus
Remate (outer)
DNA · 3 values
Petals · Dots · Smooth
Stroke
DNA · 4 weighted
Hairline · Thin · Medium · Bold
Núcleo (halo)
DNA · 3 weighted
None · Halo · Double Halo
Modifier
DNA · 5 rare (20% total)
None · Golden · Prismatic · Inverse · Halo Glow
Era
Dynamic · 4 tiers
Genesis · Young · Mature · Ancestral
Stage
Dynamic · 8 tiers
0–7 (log on transfer count)
Transfers
Dynamic · uint16
0 — 65,535
* * *

Frequently Asked

If something isn't here, the answer is probably "read the contract."

Is this really 100% onchain?
Yes. The SVG is generated inside tokenURI() on every call. No IPFS, no Arweave, no proxy server. Pull the contract source from Etherscan, run eth_call against any node — the image is reproducible bit-for-bit forever.
What changes when I transfer?
The contract increments a per-token counter. The renderer reads that counter and adjusts the composition — denser motifs, accent bands, satellite dots, alternate-ring color reinforcement. Across 8 logarithmic stages (0 → 7), the piece grows from genesis to ancestral.
Why are Heraldia holders special?
Heraldia laid the path for fully onchain SVG evolution on mainnet. We are downstream of that work. As recognition, holders get free claims tiered by holdings, proven via Merkle snapshot taken before launch.
What does CC0 mean?
Public domain. Anyone can remix, sell merch, fork the renderer, print and frame. We assert no rights over the art. The chain assigns ownership of the token; the work itself belongs to no one and everyone.
Will the renderer change after launch?
The renderer is upgradeable until lockRenderer() is called. Intent: launch, validate, lock irreversibly. After locked, rendering logic is immutable forever.
Can I be both a Heraldia claimant AND a public minter?
Yes. Free claim and paid mint share the same per-wallet cap of 25. A 10-Heraldia holder could claim 10 free and mint 15 paid, hitting the cap at 25 total.
What's the cost to mint?
0.0001 ETH per token (~$0.20). Plus network fees, which vary. Batch minting amortizes fixed transaction overhead.
Is there a wallet cap?
Yes — 25 per wallet, counting both paid and free claims. Per-transaction cap is also 25. Cap is enforced on the receiver, so airdrops don't bypass it.
What about royalties?
ERC-2981 standard. 5% on secondary sales, hardcoded to a single dev wallet. Not enforced via Operator Filter — marketplaces honor royalties at their discretion.
What network?
Ethereum Mainnet. Layer 1. Where Heraldia lives. Where permanence is most expensive — and most credible.
Can I render this anywhere?
Yes. Any client that can call tokenURI(id) on the contract gets the full SVG as a data URI. Frame it in a hardware wallet, print it on a tote, mount it in an LED wall.