/\_/\ (o.o) > ^ <asciipets
Documentation

How asciipets works

A complete description of the mechanism: what you are buying, where the money comes from, exactly how your share is calculated, and what this system does not promise.

Overview

asciipets.fun is a collection of 1000 ASCII animals on Solana. You mint one by burning 1,000,000 $ASCII. Every buy and sell of $ASCII pays a small fee into the reward pool, and your pet earns a share of that pool, paid out in SOL.

The unusual part is that your share is not fixed. Every pet has a rarity weight, and that weight goes up or down with a vitality score based on how you actually trade. Trade well and your pet thrives and earns its full share. Stop trading, churn, or blow up an account and it gets hungry, then goes dormant and earns nothing until your numbers recover.

The one-sentence version

Your pet earns a share of the reward pool, and how big that share is depends on how well you trade.

Quick start

  1. 1
    Connect a Solana wallet

    Phantom, Solflare, Backpack or any detected wallet. No email or social login; the wallet is the account.

  2. 2
    Hold 1,000,000 $ASCII

    The exact mint cost. It is burned, not transferred.

  3. 3
    Press burn

    Your wallet signs one transaction. A random unminted pet is assigned once the burn confirms on-chain, and you land on its page.

  4. 4
    Keep trading

    Your wallet is scored over a rolling 30 days. The score sets your pet's health, and health sets its share.

  5. 5
    Claim

    Rewards accumulate as the keeper sweeps fees. Claim whenever you like; it pays out in SOL.

The collection

There are exactly 1000 pets, and there will never be more. The cap is enforced by the database itself rather than by a counter in the code, so there is no setting anywhere that could be changed to mint the 1001st.

You can browse the whole collection before burning anything. Every pet, its art, its traits and its rarity are on the board from day one, so you can see exactly what is out there instead of taking our word for it.

Supply
1000
Species
24
Gaze variants
10
Appetite variants
9
Coat variants
10
Charm variants
7
Possible combinations
151,200

How pets are generated

A pet is not stored anywhere. It is worked out from its number: the same generator turns 42 into a species, a gaze, an appetite, a coat and a charm, and gives the identical answer on our server, in your browser, and in the process that pays everyone.

Nothing about a pet is decided when you mint it. Minting only records who owns which pet. Everything else is worked out on the spot, so there is no saved copy of a pet's traits that could end up disagreeing with the art in front of you.

With five traits drawn from around 50,000 combinations, some pets were always going to come out identical. When that happens the generator re-rolls that pet until it lands on something free. All 1000 are checked and confirmed unique.

Traits

Every pet has five traits. Their names describe the mechanic rather than the anatomy, because on this board a pet's job is to earn.

Species
Which animal. 24 of them, with deliberately unalike silhouettes.
Gaze
How alert it is to your book. Drowsy at the common end, Laser-Eyed at the rare end.
Appetite
How hard it feeds on the pool. Grazing through to Insatiable.
Coat
Its colour. Ash and Moss are common; Frost and Gold are not.
Charm
What the yield hangs off. Most pets have none; a few wear a Crown or a Halo.

Each trait option carries a point value. Rarity is not rolled separately — it is the sum of what a pet happens to be wearing. That means a Legendary is legendary because of what you can see on it, and the tier on the card can always be explained by pointing at the art.

Rarity tiers

Add up a pet's trait points and the total decides its tier. The cutoffs come from counting the collection we actually generated, not from picking round numbers — guessing at them is how a collection ends up with two Epics and no Legendary at all.

TierPointsCountShareBase weight
Legendary14+40.4%6.0x
Epic11+272.7%3.6x
Rare8+10110.1%2.4x
Uncommon5+24524.5%1.6x
Common0+62362.3%1.0x

Base weight is a ratio, not an amount. A Legendary earns six times what a Common earns from the same pool at the same health. It is six times the share, not six of anything fixed — the pool is only ever what the fees add up to.

Minting

Burn 1,000,000 $ASCII and you are assigned a random pet from whatever is still unminted. The draw uses a cryptographic random source and picks evenly from what is left, so every remaining pet is equally likely.

Why you cannot pick one

If you could choose, the first buyers would simply take the five Legendaries and the collection would be picked over before most people arrived. A random draw is the only version where minting on day thirty is the same bet as minting on day one.

Minting happens in two steps. We build the burn transaction, your wallet signs it, and then we read the confirmed transaction back off the chain before assigning a pet. The only thing passed between the two steps is the transaction signature, which we check against the chain rather than take on trust.

If your browser closes right after the burn goes through, nothing is lost. Coming back and finishing gives you the pet that burn already paid for — it will not charge you twice or hand out a second pet.

The burn

The tokens are destroyed. They do not go to a treasury, a multisig or a dev wallet; the total supply of $ASCII permanently decreases by 1,000,000 and nobody — including us — can spend them.

The burn uses burnChecked rather than burn, which means the amount is checked against the token's decimals and the whole transaction is rejected if they disagree. Burning cannot be undone, and getting an amount wrong by a factor of a thousand is the usual way that happens, so the extra check is worth it.

To confirm a burn we compare your token balance before and after, and check the tokens did not simply land in another account. Looking for a specific instruction instead would mean guessing which of several ways the tokens were destroyed, and every one of those guesses is a chance to miss a real burn or, worse, accept a transfer pretending to be one.

Supply guarantees

No pet can be minted twice
The pet index is a primary key. A second insert on the same index fails at the database, not in application logic.
No burn can be redeemed twice
The burn signature carries a unique constraint. Replaying it returns the original pet.
There is no 1001st pet
The index column has a check constraint of 1 to 1000. The cap is structural.
Nobody can mint without burning
A pet is only assigned after a confirmed on-chain burn signed by the claiming wallet is re-read from the chain.

Where the money comes from

Every buy and sell of $ASCII pays a small fee into the reward pool. About once a minute we collect whatever has built up and split it between the live pets, in proportion to their weight.

There is no fixed rate and no APR. If nothing has been traded, there is nothing to pay out. Everything a pet receives is money already collected, so we can never pay out more than came in.

What this means in practice

The more $ASCII gets traded, the more there is to share. A quiet week pays very little, and the site will show you that rather than an estimate.

Vitality

A pet does not eat. What keeps it going is how you trade, scored from your on-chain history over the last 30 days: your profit and loss per token, what you put in, how often you traded, and how your net worth moved day to day.

Vitality is a score out of 100, made of five parts. We show you all five rather than just the total, because a single number that quietly halves what you earn is the fastest way to lose your trust.

Every part is capped, and that is the important bit. Without a cap, one wallet showing a paper 500x on a token nobody can actually sell would take the entire pool.

The five components

ComponentWeightWhat it measures
Profitability35%Return on capital actually deployed
Consistency20%Win rate, shrunk toward the mean by sample size
Activity15%Trading at all, without churning
Conviction20%Still holding $ASCII
Discipline10%Maximum drawdown on your equity curve

Profitability — 35%

Total P&L divided by the cost basis you actually deployed, passed through a tanh curve. Return on capital is unbounded in both directions and the tails are where manipulation lives; tanh maps the whole real line into 0–1 with the useful resolution in the ±100% band where real traders sit.

Unrealised gains count at half. A wallet holding an illiquid token at its last print is not up that money in any sense that survives a sell. Halving the unrealised leg is the cheapest defence against a wallet minting its own token, printing one trade at an absurd price, and farming the pool forever.

A cost basis below $50 is treated as $50, because a $3 basis returning 400% is noise rather than a trader.

Consistency — 20%

Your win rate across closed positions, Beta-smoothed toward the average by how many you have actually closed. One win out of one trade is not a 100% win rate, and without shrinkage the top of the board would be entirely wallets with a single lucky close.

Activity — 15%

A saturating curve on trade count, penalised at the top end. Both failure modes are real: a wallet that never trades gives nothing to score, and a wallet running a thousand wash swaps a day is manufacturing a score rather than earning one.

Silence decays the term. A wallet quiet for more than three days starts losing this component on an exponential, so a good month a year ago does not keep paying forever.

Conviction — 20%

Whether you still hold $ASCII. Logarithmic, so the difference between holding nothing and holding one mint's worth is most of the score and whaling past that buys very little. This is a liveness check, not a second rarity axis for people with money.

Discipline — 10%

Maximum peak-to-trough drawdown on your actual net-worth curve. This is the component realised P&L cannot express: two wallets can bank the same profit, and the one that round-tripped 90% of its net worth getting there is not the same trader as the one that did not.

A 20% drawdown is unremarkable and costs nothing. The penalty ramps from there and bottoms out at 80%, past which a wallet has already been wiped out once and finer resolution says nothing useful. Wallets too new to have a curve fall back to loss concentration instead, because scoring an unreadable curve as a flawless one would make every fresh wallet look maximally disciplined.

Health states

Vitality lands your pet in one of five states, and the state sets the multiplier applied to its rarity weight.

StateVitalityMultiplierEffect
Thriving75+1.25xEarns above its base weight
Healthy50+1xEarns its base weight
Hungry30+0.6xEarns a fraction of its base weight
Starving15+0.25xEarns a fraction of its base weight
Dormant0+0xAccrues nothing

These are steps rather than a smooth curve, on purpose. With a smooth curve your share would move every time any price ticked and you would never be able to tell whether you were being paid correctly. Steps give you a status you can read and a clear number to aim at.

Dormant is not death

A dormant pet is not destroyed, does not expire, and cannot be taken away from you. It stops earning and starts again as soon as your numbers recover. A bad month costs you income, never the pet.

Streaks

Every UTC day your wallet scores 50 or better (Healthy or above), your streak advances by one. The streak adds 1% to your effective weight per day, capped at 25%.

A missed day resets it rather than pausing it. The streak can advance at most once per UTC day regardless of how many times you are rescored, so refreshing the page in a loop does nothing.

Weights and shares

A pet's effective weight is the product of three things:

effective weight = rarity weight x health multiplier x (1 + streak bonus)

And its share of any given sweep is its weight over the sum of every live pet's weight:

share = effective weight / total effective weight of all live pets

This is why the share percentage shown on the board moves even when you have done nothing: it is a fraction of a total, and the total changes as other people mint, recover or lapse.

A worked example
  • A Rare pet has a base weight of 2.4x.
  • Its owner scores 82 vitality, which is Thriving: a 1.25x multiplier.
  • They have a 12-day streak: a 1.12x bonus.
  • Effective weight = 2.4 x 1.25 x 1.12 = 3.36
  • If every live pet together sums to 400 weight, this pet takes 3.36 / 400 = 0.84% of each sweep.

Distribution maths

Whatever amount we collect is exactly the amount we hand out. Splitting it uses largest-remainder apportionment rather than plain division.

That matters more than it sounds. Plain division loses money to rounding: a hundred pets splitting 99 lamports would each round down to zero and the whole lot would quietly disappear, every single time. Largest remainder gives the leftovers to whoever was rounded down hardest, so the parts always add back up to the total.

We work out everyone's share before collecting. If we collected first and then could not reach the database, the money would be sitting there with nobody credited for it. Better to find out something is wrong while the fees are still safe where they are, ready to be collected next time.

If there are no live pets at all, we do not collect. There would be nobody to split it between, and moving it somewhere with no claimants is worse than leaving it alone.

Claiming

Your rewards build up as fees are collected. Press claim and we send the balance to your wallet in SOL. There is a small minimum, so that a claim is always worth more than the transaction fee to send it.

Your balance is deducted before the SOL is sent. That feels like the wrong way round and it is the right one: doing it the other way loses money any time something fails in between, and lets two browser tabs clicking claim at the same moment both read the same balance and both get paid.

Deducting first makes that impossible — a second claim arriving at the same time waits, then finds nothing left to take. The trade-off is that if the transfer fails we have to put the money back, which is exactly what happens, and the failed attempt is recorded either way.

Security model

Authentication
Privy issues a signed access token when you connect. The server verifies it against Privy's public JWKS on every request — a signature check against a cached key, so it cannot fail open because a third party is down.
Wallet ownership
The token identifies a user, not which of their wallets a request is about. The claimed wallet is checked against the user's linked accounts before anything is paid to it.
Database access
The browser never reaches Postgres. Row-level security is on with no policies, which denies the anonymous key outright; every read and write goes through a server route.
Burn verification
Re-read from the chain by signature, checked for a real supply reduction signed by the claiming wallet. The client is trusted for nothing but the signature string.
Mint assignment
Decided server-side after verification. The browser never says which pet it received.

Risks and limits

This section exists because the honest version of this product has to include it.

The payout is operational, not on-chain
The treasury key is held by whoever runs the keeper, not by a smart contract. That creator fees pay the pets is a commitment we keep, not something the chain enforces. The burn is on-chain and irreversible; the payout is us.
The pool can be zero
If nobody trades $ASCII, there are no creator fees, and pets earn nothing. There is no floor, no reserve and no subsidy.
Vitality depends on a third party
Scores are computed from Birdeye data. If it is unavailable, scores go stale rather than wrong — the last stored score keeps being used, so distributions never block on an API being up.
Burning is irreversible
There is no refund path. If you burn and never mint, the confirm step can still be replayed to recover your pet, but the tokens are gone regardless.
Scores can move against you
A bad month lowers your vitality and therefore your share. This is the mechanic working as designed, not a malfunction.

Glossary

Vitality
A 0–100 score derived from your 30-day on-chain trading record.
Health
The tier your vitality falls into, which sets your multiplier.
Base weight
The rarity-derived share weight of a pet at full health.
Effective weight
Base weight after the health multiplier and streak bonus.
Share
Your effective weight as a fraction of every live pet's.
Sweep
One keeper collection of accumulated creator fees.
Distribution
The split of one sweep across live pets.
Accrued
Credited to your pets and not yet withdrawn.
Live pet
A minted pet whose owner scores above Dormant.
Drawdown
The largest peak-to-trough fall in your net worth over the window.

FAQ

Can I choose which pet I get?+

No. A random unminted pet is assigned after your burn confirms, drawn evenly from everything still available. You can browse the whole collection beforehand, but not reserve from it.

Can I sell or transfer my pet?+

Ownership is recorded against your wallet address. There is no transfer function today.

What happens if I stop trading?+

Your Activity component decays after three quiet days and your vitality falls. Below 15 the pet goes dormant and accrues nothing until you trade again. It is never destroyed.

Does holding more $ASCII earn me more?+

Barely. Conviction is logarithmic and caps out around four times the mint cost. It is a liveness check, not a way to buy yield.

Why did my share go down when my score did not change?+

Share is a fraction of the total weight of all live pets. If other people mint or recover, the denominator grows and your slice narrows even though your own weight is unchanged.

How often does the pool pay out?+

The keeper sweeps roughly once a minute, but only when enough has accrued to be worth the transaction fee. Quiet periods produce no sweeps at all.

Do multiple pets stack?+

Yes. Each pet you own carries its own weight, and all of them are scored by the same wallet vitality.

Is unrealised profit counted?+

At half weight. A paper gain on an illiquid token is not money that survives a sell, and counting it in full would be trivially farmable.