Supply
FP is one token seen from three chains. It exists on Base; the balances on Ethereum mainnet and Arbitrum are LayerZero OFT deployments, backed one-for-one by FP locked in an adapter contract on Base. Adding the three totals together would count the same tokens twice.
Unified supply
7.18M FP
unified = (Base − locked) + mainnet + Arbitrum. Bridge-locked FP on Base backs everything circulating on Ethereum mainnet and Arbitrum, so the locked balance cancels and the unified figure is Base totalSupply. It reduces exactly only when locked equals the remote supplies; the difference is the residual below.
| Base totalSupply | 7,183,719.068346138385943347 | |
| locked in the adapter | − | 2,697,447.875985 |
| circulating on Base | 4,486,271.192361138385943347 | |
| Ethereum mainnet totalSupply | + | 2,697,324.112915 |
| Arbitrum totalSupply | + | 9 |
| accounted for | 7,183,604.305276138385943347 | |
| Base totalSupply | 7,183,719.068346138385943347 | |
| difference (residual) | 114.76307 |
All figures in FP, exact
That residual is stated in full under Bridge, below.
One contract, three names
The token launched on Base as the game token for Fren Pet. It was later renamed VIBE, then Identity.md. Renames only — the same contract, the same holders and the same supply throughout.
The rename is still visible on chain — the deployments answer name() differently, as the table below shows. VIBE is background, not a reading from this snapshot.
It was born on Base and bridged to Ethereum mainnet and Arbitrum as a LayerZero OFT. The genesis supply was 10,000,000 FP; everything below that figure is cumulative destruction.
The game itself is documented by its own site, frenpet.xyz.
Per chain
| chain | name() | symbol() | totalSupply | block | read at (UTC) |
|---|---|---|---|---|---|
| Base | Fren Pet | Fren Pet | 7.18M | 50,060,083 | 2026-08-16 19:45:13 |
| Ethereum mainnet | Identity.md | IMD | 2.70M | 25,769,802 | 2026-08-16 19:45:11 |
| Arbitrum | Fren Pet | FP | 9.00 | 495,243,366 | 2026-08-16 19:45:13 |
The mainnet deployment answers with the Identity.md name and the IMD symbol; the Base and Arbitrum deployments still answer with the Fren Pet names. Same asset, per-deployment metadata — this is what the contracts return, not a mismatch to be corrected. The Base deployment answers symbol() with the full name rather than a ticker; that too is read, not tidied.
Arbitrum holds 9 FP. Nine tokens, not nine thousand: a deployed endpoint that is essentially unused.
Split as of Base block 50060083 / mainnet block 25769802 / Arbitrum block 495243366 — this split moves with every bridge transaction; it is a snapshot of a moment, not a stable fact.
Bridge
| adapter contract (Base) | 0xab152db8aaC047b6757fFCF495FfE88d7712690A |
| FP locked in the adapter | 2,697,447.875985 (37.5495% of Base supply) |
| circulating on mainnet + Arbitrum | 2,697,333.112915 |
| residual (locked − circulating) | +114.76307 (0.004255% of locked) |
The residual is positive: more FP is locked on Base than is circulating on the remote chains. That is the safe direction — backing without circulation. The reverse would mean supply existed remotely without backing, and the snapshot script refuses to write a file in that case.
Destroyed since genesis
2.82M FP
28.16% of the 10,000,000 FP genesis supply
Genesis supply minus Base totalSupply(). Supply that no longer exists.
Scope: the 10,000,000 FP genesis figure only. Historical constant, not a reading from this run: recovering it from chain needs a mint-log sweep, which the free-tier 10-block eth_getLogs cap puts out of reach.
Held at 0x…dEaD
45.377039024748604149 FP
Held at the conventional burn address, still counted inside totalSupply(). Reported separately and never folded into the destruction figure above, which is supply that no longer exists — adding the two would double-count.
Named contract holdings
| contract | address (Base) | FP held | % of Base supply |
|---|---|---|---|
| OFT adapter (bridge lockbox) | 0xab152db8aaC047b6757fFCF495FfE88d7712690A | 2,697,447.875985 | 37.5495 |
| game contract | 0x0e22B5f3E11944578b37ED04F5312Dfc246f443C | 334,954.157725308043234495 | 4.6627 |
| FP/WETH pool (main venue) | 0xDE66c35e01ED8e619Bf092352338ef94f2327337 | 246,004.929209846510874905 | 3.4245 |
| FP/WETH pool (uniswapV2Pair pointer) | 0x29b3a7869E3662D00aaBD89A8ee74B2F703a6a66 | 821.080692804664902861 | 0.0114 |
| keeper | 0x065bf5a7AF15c52C91353990CC8F3d97A1595CE7 | 610 | 0.0085 |
Balances of addresses this repository already names. Nothing is named here that was not already labelled elsewhere in the repo, and no attempt is made to identify any other holder.
Method
One pinned block per chain, all three heights taken back-to-back and every timestamp read from chain; within a chain every read goes through Multicall3 at the pinned height. Addresses are derived from chain state — mainnet peers() names the Base adapter and the Arbitrum OFT, and the adapter's token() names the Base token. decimals() is read on all three chains. All arithmetic is bigint on raw values; no float touches a figure.
Three pins, taken back-to-back: Ethereum mainnet block 25,769,802, Base block 50,060,083, Arbitrum block 495,243,366 — 2 seconds of wall-clock spread between the earliest and latest, measured from timestamps read from each chain rather than assumed from a block-time formula.
10 controls passed before this file was written, each printing what it expected before it ran. Nothing was written on a failure.
| figure | source |
|---|---|
| unified supply | Base totalSupply() at Base block 50060083, via Multicall3 |
| Base totalSupply | totalSupply() on 0xFF0C532FDB8Cd566Ae169C1CB157ff2Bdc83E105 at Base block 50060083, via Multicall3 |
| Ethereum mainnet totalSupply | totalSupply() on 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7 at mainnet block 25769802, via Multicall3 |
| Arbitrum totalSupply | totalSupply() on 0x374080d830B66A3E4c8ecbCa846E922A2039A024 at Arbitrum block 495243366, via Multicall3 |
| adapter address | mainnet peers(30184) at mainnet block 25769802, then token() on the peer at Base block 50060083 |
| FP locked | balanceOf(adapter) on 0xFF0C532FDB8Cd566Ae169C1CB157ff2Bdc83E105 at Base block 50060083, via Multicall3 |
| destroyed since genesis | 10,000,000 FP genesis minus Base totalSupply() at Base block 50060083 |
| 0x…dEaD balance | balanceOf(0x…dEaD) on 0xFF0C532FDB8Cd566Ae169C1CB157ff2Bdc83E105 at Base block 50060083, via Multicall3 |
| named contract holdings | balanceOf(address) on 0xFF0C532FDB8Cd566Ae169C1CB157ff2Bdc83E105 at Base block 50060083, via Multicall3 |